Skip to content

feat: Add quotes rule#381

Open
bjyberg wants to merge 10 commits intoetiennebacher:mainfrom
bjyberg:feat/quote
Open

feat: Add quotes rule#381
bjyberg wants to merge 10 commits intoetiennebacher:mainfrom
bjyberg:feat/quote

Conversation

@bjyberg
Copy link
Contributor

@bjyberg bjyberg commented Mar 6, 2026

I may have been a bit ambitious with my abilities on this one, but I think I got there in the end. I often find myself missing the quote style lint and fix from Lintr and Styler, so that gave me some motivation to try and implement it.

It should implement the same behavior as the Quotes linter from lintr. I did a lot of copying from the assignment linter, undesirable function linter, etc. I took most of the tests from Linter as well.

Let me know what you think, any changes, whether you want to include this now or not, etc.

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Ecosystem checks

easystats/datawizard: +2 -0 violations
New violations (first 100):
tests/testthat/test-data_modify.R[305:41]: quotes -- Only use double-quotes.
tests/testthat/test-data_modify.R[307:35]: quotes -- Only use double-quotes.  
lrberge/stringmagic: +5 -0 violations
New violations (first 100):
R/string_magic_main.R[1011:61]: quotes -- Only use double-quotes.
R/string_magic_main.R[1565:20]: quotes -- Only use double-quotes.
R/string_magic_main.R[3397:12]: quotes -- Only use double-quotes.
R/test_funs.R[157:41]: quotes -- Only use double-quotes.
R/test_funs.R[158:41]: quotes -- Only use double-quotes.  
nlmixr2/nlmixr2est: +5 -0 violations
New violations (first 100):
build/test_install.R[96:18]: quotes -- Only use double-quotes.
build/test_install.R[96:34]: quotes -- Only use double-quotes.
build/test_install.R[96:43]: quotes -- Only use double-quotes.
tests/testthat/test-table-cmt.R[84:10]: quotes -- Only use double-quotes.
tests/testthat/test-table-cmt.R[131:33]: quotes -- Only use double-quotes.  
pola-rs/r-polars: +14 -0 violations
New violations (first 100):
R/000-wrappers.R[397:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[438:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[471:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[764:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[883:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[3632:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4112:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4158:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4201:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4258:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4415:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4749:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4790:6]: quotes -- Only use double-quotes.
R/000-wrappers.R[4823:6]: quotes -- Only use double-quotes.  
RcppCore/RcppArmadillo: +2 -0 violations
New violations (first 100):
inst/examples/varSimulation.r[53:8]: quotes -- Only use double-quotes.
inst/tinytest/test_Rlapack.R[23:15]: quotes -- Only use double-quotes.  
Rdatatable/data.table: +323 -0 violations
New violations (first 100):
R/AllS4.R[6:23]: quotes -- Only use double-quotes.
R/AllS4.R[6:37]: quotes -- Only use double-quotes.
R/IDateTime.R[43:38]: quotes -- Only use double-quotes.
R/IDateTime.R[67:13]: quotes -- Only use double-quotes.
R/IDateTime.R[69:13]: quotes -- Only use double-quotes.
R/IDateTime.R[69:24]: quotes -- Only use double-quotes.
R/IDateTime.R[69:33]: quotes -- Only use double-quotes.
R/IDateTime.R[114:21]: quotes -- Only use double-quotes.
R/IDateTime.R[156:43]: quotes -- Only use double-quotes.
R/IDateTime.R[159:36]: quotes -- Only use double-quotes.
R/IDateTime.R[189:36]: quotes -- Only use double-quotes.
R/IDateTime.R[194:34]: quotes -- Only use double-quotes.
R/IDateTime.R[211:16]: quotes -- Only use double-quotes.
R/IDateTime.R[332:18]: quotes -- Only use double-quotes.
R/IDateTime.R[332:47]: quotes -- Only use double-quotes.
R/IDateTime.R[333:18]: quotes -- Only use double-quotes.
R/IDateTime.R[338:18]: quotes -- Only use double-quotes.
R/IDateTime.R[338:47]: quotes -- Only use double-quotes.
R/IDateTime.R[339:18]: quotes -- Only use double-quotes.
R/IDateTime.R[344:18]: quotes -- Only use double-quotes.
R/IDateTime.R[344:47]: quotes -- Only use double-quotes.
R/IDateTime.R[345:18]: quotes -- Only use double-quotes.
R/as.data.table.R[29:15]: quotes -- Only use double-quotes.
R/as.data.table.R[41:17]: quotes -- Only use double-quotes.
R/as.data.table.R[53:20]: quotes -- Only use double-quotes.
R/as.data.table.R[53:25]: quotes -- Only use double-quotes.
R/as.data.table.R[55:20]: quotes -- Only use double-quotes.
R/as.data.table.R[109:17]: quotes -- Only use double-quotes.
R/as.data.table.R[165:88]: quotes -- Only use double-quotes.
R/as.data.table.R[264:74]: quotes -- Only use double-quotes.
R/as.data.table.R[267:20]: quotes -- Only use double-quotes.
R/as.data.table.R[297:13]: quotes -- Only use double-quotes.
R/between.R[13:119]: quotes -- Only use double-quotes.
R/between.R[15:119]: quotes -- Only use double-quotes.
R/between.R[59:35]: quotes -- Only use double-quotes.
R/bmerge.R[197:18]: quotes -- Only use double-quotes.
R/bmerge.R[203:58]: quotes -- Only use double-quotes.
R/cedta.R[68:54]: quotes -- Only use double-quotes.
R/data.table.R[84:19]: quotes -- Only use double-quotes.
R/data.table.R[271:55]: quotes -- Only use double-quotes.
R/data.table.R[271:88]: quotes -- Only use double-quotes.
R/data.table.R[518:19]: quotes -- Only use double-quotes.
R/data.table.R[734:54]: quotes -- Only use double-quotes.
R/data.table.R[820:36]: quotes -- Only use double-quotes.
R/data.table.R[868:29]: quotes -- Only use double-quotes.
R/data.table.R[869:63]: quotes -- Only use double-quotes.
R/data.table.R[889:29]: quotes -- Only use double-quotes.
R/data.table.R[890:65]: quotes -- Only use double-quotes.
R/data.table.R[936:55]: quotes -- Only use double-quotes.
R/data.table.R[976:29]: quotes -- Only use double-quotes.
R/data.table.R[976:37]: quotes -- Only use double-quotes.
R/data.table.R[993:494]: quotes -- Only use double-quotes.
R/data.table.R[1001:23]: quotes -- Only use double-quotes.
R/data.table.R[1005:23]: quotes -- Only use double-quotes.
R/data.table.R[1045:30]: quotes -- Only use double-quotes.
R/data.table.R[1047:66]: quotes -- Only use double-quotes.
R/data.table.R[1049:32]: quotes -- Only use double-quotes.
R/data.table.R[1062:85]: quotes -- Only use double-quotes.
R/data.table.R[1162:29]: quotes -- Only use double-quotes.
R/data.table.R[1435:22]: quotes -- Only use double-quotes.
R/data.table.R[1442:35]: quotes -- Only use double-quotes.
R/data.table.R[1442:49]: quotes -- Only use double-quotes.
R/data.table.R[1443:22]: quotes -- Only use double-quotes.
R/data.table.R[1460:22]: quotes -- Only use double-quotes.
R/data.table.R[1463:22]: quotes -- Only use double-quotes.
R/data.table.R[1491:22]: quotes -- Only use double-quotes.
R/data.table.R[1494:25]: quotes -- Only use double-quotes.
R/data.table.R[1496:13]: quotes -- Only use double-quotes.
R/data.table.R[1498:27]: quotes -- Only use double-quotes.
R/data.table.R[1596:40]: quotes -- Only use double-quotes.
R/data.table.R[1668:67]: quotes -- Only use double-quotes.
R/data.table.R[1780:25]: quotes -- Only use double-quotes.
R/data.table.R[1797:62]: quotes -- Only use double-quotes.
R/data.table.R[1834:40]: quotes -- Only use double-quotes.
R/data.table.R[1946:22]: quotes -- Only use double-quotes.
R/data.table.R[1974:20]: quotes -- Only use double-quotes.
R/data.table.R[1983:20]: quotes -- Only use double-quotes.
R/data.table.R[1983:29]: quotes -- Only use double-quotes.
R/data.table.R[2607:17]: quotes -- Only use double-quotes.
R/data.table.R[2609:31]: quotes -- Only use double-quotes.
R/data.table.R[2609:51]: quotes -- Only use double-quotes.
R/data.table.R[2973:15]: quotes -- Only use double-quotes.
R/data.table.R[2973:39]: quotes -- Only use double-quotes.
R/data.table.R[2991:39]: quotes -- Only use double-quotes.
R/data.table.R[3065:24]: quotes -- Only use double-quotes.
R/data.table.R[3118:49]: quotes -- Only use double-quotes.
R/data.table.R[3118:54]: quotes -- Only use double-quotes.
R/data.table.R[3118:59]: quotes -- Only use double-quotes.
R/data.table.R[3187:34]: quotes -- Only use double-quotes.
R/data.table.R[3193:36]: quotes -- Only use double-quotes.
R/data.table.R[3408:21]: quotes -- Only use double-quotes.
R/data.table.R[3411:23]: quotes -- Only use double-quotes.
R/data.table.R[3411:31]: quotes -- Only use double-quotes.
R/duplicated.R[16:16]: quotes -- Only use double-quotes.
R/duplicated.R[40:14]: quotes -- Only use double-quotes.
R/duplicated.R[112:19]: quotes -- Only use double-quotes.
R/fcast.R[31:10]: quotes -- Only use double-quotes.
R/fcast.R[46:22]: quotes -- Only use double-quotes.
R/fcast.R[59:22]: quotes -- Only use double-quotes.
R/fcast.R[81:20]: quotes -- Only use double-quotes.  
rstudio/shiny: +627 -0 violations
New violations (first 100):
R/bind-cache.R[576:43]: quotes -- Only use double-quotes.
R/bind-cache.R[576:66]: quotes -- Only use double-quotes.
R/bind-cache.R[577:43]: quotes -- Only use double-quotes.
R/bind-cache.R[577:66]: quotes -- Only use double-quotes.
R/bind-event.R[200:12]: quotes -- Only use double-quotes.
R/bind-event.R[272:33]: quotes -- Only use double-quotes.
R/bookmark-state.R[321:39]: quotes -- Only use double-quotes.
R/bootstrap.R[1280:15]: quotes -- Only use double-quotes.
R/bootstrap.R[1282:14]: quotes -- Only use double-quotes.
R/bootstrap.R[1283:16]: quotes -- Only use double-quotes.
R/bootstrap.R[1295:15]: quotes -- Only use double-quotes.
R/bootstrap.R[1297:14]: quotes -- Only use double-quotes.
R/bootstrap.R[1298:16]: quotes -- Only use double-quotes.
R/fileupload.R[36:2]: quotes -- Only use double-quotes.
R/fileupload.R[77:47]: quotes -- Only use double-quotes.
R/fileupload.R[96:2]: quotes -- Only use double-quotes.
R/fileupload.R[100:17]: quotes -- Only use double-quotes.
R/imageutils.R[2:27]: quotes -- Only use double-quotes.
R/imageutils.R[7:24]: quotes -- Only use double-quotes.
R/imageutils.R[91:52]: quotes -- Only use double-quotes.
R/input-checkboxgroup.R[90:4]: quotes -- Only use double-quotes.
R/input-date.R[127:58]: quotes -- Only use double-quotes.
R/input-date.R[129:63]: quotes -- Only use double-quotes.
R/input-file.R[122:54]: quotes -- Only use double-quotes.
R/input-radiobuttons.R[102:4]: quotes -- Only use double-quotes.
R/input-select.R[160:34]: quotes -- Only use double-quotes.
R/input-select.R[160:51]: quotes -- Only use double-quotes.
R/input-select.R[166:30]: quotes -- Only use double-quotes.
R/input-select.R[208:8]: quotes -- Only use double-quotes.
R/input-select.R[209:47]: quotes -- Only use double-quotes.
R/input-select.R[216:6]: quotes -- Only use double-quotes.
R/input-select.R[224:13]: quotes -- Only use double-quotes.
R/input-select.R[225:60]: quotes -- Only use double-quotes.
R/input-slider.R[181:33]: quotes -- Only use double-quotes.
R/input-slider.R[181:47]: quotes -- Only use double-quotes.
R/input-slider.R[183:34]: quotes -- Only use double-quotes.
R/input-slider.R[183:49]: quotes -- Only use double-quotes.
R/input-slider.R[187:21]: quotes -- Only use double-quotes.
R/input-slider.R[188:20]: quotes -- Only use double-quotes.
R/input-slider.R[189:16]: quotes -- Only use double-quotes.
R/input-slider.R[193:23]: quotes -- Only use double-quotes.
R/input-slider.R[194:23]: quotes -- Only use double-quotes.
R/input-utils.R[62:62]: quotes -- Only use double-quotes.
R/jqueryui.R[61:37]: quotes -- Only use double-quotes.
R/jqueryui.R[61:45]: quotes -- Only use double-quotes.
R/jqueryui.R[61:53]: quotes -- Only use double-quotes.
R/jqueryui.R[61:64]: quotes -- Only use double-quotes.
R/jqueryui.R[72:12]: quotes -- Only use double-quotes.
R/jqueryui.R[72:42]: quotes -- Only use double-quotes.
R/jqueryui.R[72:51]: quotes -- Only use double-quotes.
R/jqueryui.R[73:12]: quotes -- Only use double-quotes.
R/jqueryui.R[74:26]: quotes -- Only use double-quotes.
R/jqueryui.R[74:38]: quotes -- Only use double-quotes.
R/jqueryui.R[75:14]: quotes -- Only use double-quotes.
R/jqueryui.R[75:46]: quotes -- Only use double-quotes.
R/jqueryui.R[75:54]: quotes -- Only use double-quotes.
R/jqueryui.R[77:56]: quotes -- Only use double-quotes.
R/jqueryui.R[77:72]: quotes -- Only use double-quotes.
R/jqueryui.R[77:78]: quotes -- Only use double-quotes.
R/jqueryui.R[77:87]: quotes -- Only use double-quotes.
R/jqueryui.R[89:38]: quotes -- Only use double-quotes.
R/jqueryui.R[101:34]: quotes -- Only use double-quotes.
R/jqueryui.R[101:42]: quotes -- Only use double-quotes.
R/jqueryui.R[101:50]: quotes -- Only use double-quotes.
R/jqueryui.R[101:61]: quotes -- Only use double-quotes.
R/map.R[2:2]: quotes -- Only use double-quotes.
R/middleware-shiny.R[70:38]: quotes -- Only use double-quotes.
R/middleware-shiny.R[83:71]: quotes -- Only use double-quotes.
R/middleware.R[46:17]: quotes -- Only use double-quotes.
R/middleware.R[210:39]: quotes -- Only use double-quotes.
R/middleware.R[218:16]: quotes -- Only use double-quotes.
R/middleware.R[219:14]: quotes -- Only use double-quotes.
R/middleware.R[221:14]: quotes -- Only use double-quotes.
R/middleware.R[229:42]: quotes -- Only use double-quotes.
R/middleware.R[312:31]: quotes -- Only use double-quotes.
R/middleware.R[324:46]: quotes -- Only use double-quotes.
R/middleware.R[325:21]: quotes -- Only use double-quotes.
R/middleware.R[337:48]: quotes -- Only use double-quotes.
R/middleware.R[338:39]: quotes -- Only use double-quotes.
R/middleware.R[370:26]: quotes -- Only use double-quotes.
R/middleware.R[377:17]: quotes -- Only use double-quotes.
R/middleware.R[378:42]: quotes -- Only use double-quotes.
R/mock-session.R[214:2]: quotes -- Only use double-quotes.
R/mock-session.R[233:20]: quotes -- Only use double-quotes.
R/mock-session.R[235:12]: quotes -- Only use double-quotes.
R/mock-session.R[346:47]: quotes -- Only use double-quotes.
R/mock-session.R[351:32]: quotes -- Only use double-quotes.
R/mock-session.R[353:19]: quotes -- Only use double-quotes.
R/mock-session.R[353:41]: quotes -- Only use double-quotes.
R/mock-session.R[353:62]: quotes -- Only use double-quotes.
R/mock-session.R[596:26]: quotes -- Only use double-quotes.
R/priorityqueue.R[8:2]: quotes -- Only use double-quotes.
R/priorityqueue.R[13:23]: quotes -- Only use double-quotes.
R/priorityqueue.R[68:14]: quotes -- Only use double-quotes.
R/priorityqueue.R[83:9]: quotes -- Only use double-quotes.
R/priorityqueue.R[87:12]: quotes -- Only use double-quotes.
R/priorityqueue.R[90:12]: quotes -- Only use double-quotes.
R/progress.R[61:2]: quotes -- Only use double-quotes.
R/progress.R[92:27]: quotes -- Only use double-quotes.
R/progress.R[123:35]: quotes -- Only use double-quotes.  
tidyverse/dplyr: +16 -0 violations
New violations (first 100):
R/sets.R[192:34]: quotes -- Only use double-quotes.
R/sets.R[199:34]: quotes -- Only use double-quotes.
R/summarise.R[464:4]: quotes -- Only use double-quotes.
R/ts.R[5:8]: quotes -- Only use double-quotes.
tests/testthat/test-across.R[578:25]: quotes -- Only use double-quotes.
tests/testthat/test-arrange.R[77:12]: quotes -- Only use double-quotes.
tests/testthat/test-arrange.R[77:17]: quotes -- Only use double-quotes.
tests/testthat/test-arrange.R[429:12]: quotes -- Only use double-quotes.
tests/testthat/test-arrange.R[429:17]: quotes -- Only use double-quotes.
tests/testthat/test-colwise-select.R[175:36]: quotes -- Only use double-quotes.
tests/testthat/test-colwise-select.R[175:44]: quotes -- Only use double-quotes.
tests/testthat/test-colwise-select.R[177:31]: quotes -- Only use double-quotes.
tests/testthat/test-colwise-select.R[180:31]: quotes -- Only use double-quotes.
tests/testthat/test-group-by.R[635:34]: quotes -- Only use double-quotes.
tests/testthat/test-group-by.R[635:39]: quotes -- Only use double-quotes.
tests/testthat/test-transmute.R[93:56]: quotes -- Only use double-quotes.  
tidyverse/ggplot2: +140 -0 violations
New violations (first 100):
R/annotation-raster.R[42:24]: quotes -- Only use double-quotes.
R/coord-radial.R[497:15]: quotes -- Only use double-quotes.
R/coord-radial.R[498:15]: quotes -- Only use double-quotes.
R/coord-radial.R[499:15]: quotes -- Only use double-quotes.
R/coord-radial.R[506:15]: quotes -- Only use double-quotes.
R/coord-radial.R[507:15]: quotes -- Only use double-quotes.
R/coord-radial.R[508:15]: quotes -- Only use double-quotes.
R/facet-.R[1273:21]: quotes -- Only use double-quotes.
R/facet-.R[1273:26]: quotes -- Only use double-quotes.
R/facet-.R[1279:21]: quotes -- Only use double-quotes.
R/facet-.R[1279:26]: quotes -- Only use double-quotes.
R/facet-wrap.R[134:51]: quotes -- Only use double-quotes.
R/geom-.R[459:57]: quotes -- Only use double-quotes.
R/geom-hex.R[103:45]: quotes -- Only use double-quotes.
R/geom-rug.R[17:24]: quotes -- Only use double-quotes.
R/geom-rug.R[18:22]: quotes -- Only use double-quotes.
R/geom-rug.R[18:30]: quotes -- Only use double-quotes.
R/ggproto.R[270:49]: quotes -- Only use double-quotes.
R/guide-axis-theta.R[101:29]: quotes -- Only use double-quotes.
R/guide-legend.R[627:57]: quotes -- Only use double-quotes.
R/margins.R[287:25]: quotes -- Only use double-quotes.
R/margins.R[287:38]: quotes -- Only use double-quotes.
R/margins.R[302:8]: quotes -- Only use double-quotes.
R/save.R[266:25]: quotes -- Only use double-quotes.
R/save.R[279:23]: quotes -- Only use double-quotes.
R/stat-.R[399:57]: quotes -- Only use double-quotes.
R/theme-defaults.R[273:25]: quotes -- Only use double-quotes.
R/theme-defaults.R[602:25]: quotes -- Only use double-quotes.
R/theme-defaults.R[765:25]: quotes -- Only use double-quotes.
R/utilities-help.R[69:56]: quotes -- Only use double-quotes.
R/utilities-help.R[93:6]: quotes -- Only use double-quotes.
R/utilities-help.R[94:6]: quotes -- Only use double-quotes.
R/utilities-help.R[95:6]: quotes -- Only use double-quotes.
R/utilities-help.R[96:6]: quotes -- Only use double-quotes.
R/utilities-help.R[97:6]: quotes -- Only use double-quotes.
R/utilities-help.R[98:6]: quotes -- Only use double-quotes.
icons/icons.R[322:39]: quotes -- Only use double-quotes.
icons/icons.R[322:50]: quotes -- Only use double-quotes.
icons/icons.R[405:39]: quotes -- Only use double-quotes.
icons/icons.R[405:50]: quotes -- Only use double-quotes.
icons/icons.R[435:39]: quotes -- Only use double-quotes.
icons/icons.R[435:50]: quotes -- Only use double-quotes.
icons/icons.R[447:39]: quotes -- Only use double-quotes.
icons/icons.R[447:50]: quotes -- Only use double-quotes.
icons/icons.R[458:39]: quotes -- Only use double-quotes.
icons/icons.R[458:50]: quotes -- Only use double-quotes.
icons/icons.R[472:39]: quotes -- Only use double-quotes.
icons/icons.R[472:50]: quotes -- Only use double-quotes.
tests/testthat/helper-vdiffr.R[5:72]: quotes -- Only use double-quotes.
tests/testthat/helper-vdiffr.R[5:87]: quotes -- Only use double-quotes.
tests/testthat/test-aes-calculated.R[167:54]: quotes -- Only use double-quotes.
tests/testthat/test-aes.R[190:19]: quotes -- Only use double-quotes.
tests/testthat/test-annotate.R[77:61]: quotes -- Only use double-quotes.
tests/testthat/test-annotate.R[77:68]: quotes -- Only use double-quotes.
tests/testthat/test-coord-transform.R[21:24]: quotes -- Only use double-quotes.
tests/testthat/test-facet-strips.R[134:37]: quotes -- Only use double-quotes.
tests/testthat/test-facet-strips.R[135:48]: quotes -- Only use double-quotes.
tests/testthat/test-geom-dotplot.R[66:29]: quotes -- Only use double-quotes.
tests/testthat/test-geom-hline-vline-abline.R[42:35]: quotes -- Only use double-quotes.
tests/testthat/test-geom-path.R[71:82]: quotes -- Only use double-quotes.
tests/testthat/test-geom-polygon.R[4:30]: quotes -- Only use double-quotes.
tests/testthat/test-geom-rug.R[3:61]: quotes -- Only use double-quotes.
tests/testthat/test-geom-rug.R[34:63]: quotes -- Only use double-quotes.
tests/testthat/test-geom-smooth.R[12:25]: quotes -- Only use double-quotes.
tests/testthat/test-geom-smooth.R[17:44]: quotes -- Only use double-quotes.
tests/testthat/test-guide-colorbar.R[70:35]: quotes -- Only use double-quotes.
tests/testthat/test-guide-colorbar.R[70:51]: quotes -- Only use double-quotes.
tests/testthat/test-guide-colorbar.R[76:12]: quotes -- Only use double-quotes.
tests/testthat/test-guide-colorbar.R[76:28]: quotes -- Only use double-quotes.
tests/testthat/test-guides.R[494:35]: quotes -- Only use double-quotes.
tests/testthat/test-guides.R[499:35]: quotes -- Only use double-quotes.
tests/testthat/test-guides.R[504:35]: quotes -- Only use double-quotes.
tests/testthat/test-guides.R[509:49]: quotes -- Only use double-quotes.
tests/testthat/test-performance.R[33:22]: quotes -- Only use double-quotes.
tests/testthat/test-performance.R[33:27]: quotes -- Only use double-quotes.
tests/testthat/test-performance.R[33:32]: quotes -- Only use double-quotes.
tests/testthat/test-position-collide.R[3:49]: quotes -- Only use double-quotes.
tests/testthat/test-position-collide.R[5:51]: quotes -- Only use double-quotes.
tests/testthat/test-scale-binned.R[72:10]: quotes -- Only use double-quotes.
tests/testthat/test-scale-binned.R[87:10]: quotes -- Only use double-quotes.
tests/testthat/test-scale-brewer.R[6:36]: quotes -- Only use double-quotes.
tests/testthat/test-scale-brewer.R[12:35]: quotes -- Only use double-quotes.
tests/testthat/test-stat-ydensity.R[11:29]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[19:65]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[20:57]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[28:63]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[29:55]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[32:57]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[33:34]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[45:53]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[46:56]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[66:46]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[67:37]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[69:15]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[80:46]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[81:37]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[107:74]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[108:57]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[113:72]: quotes -- Only use double-quotes.
tests/testthat/test-theme.R[114:55]: quotes -- Only use double-quotes.  
vincentarelbundock/marginaleffects: +8 -0 violations
New violations (first 100):
inst/tinytest/test-comparisons.R[80:29]: quotes -- Only use double-quotes.
inst/tinytest/test-comparisons.R[80:42]: quotes -- Only use double-quotes.
inst/tinytest/test-comparisons.R[81:34]: quotes -- Only use double-quotes.
inst/tinytest/test-comparisons.R[90:16]: quotes -- Only use double-quotes.
inst/tinytest/test-comparisons.R[95:16]: quotes -- Only use double-quotes.
sandbox/methods_logitr.R[18:12]: quotes -- Only use double-quotes.
sandbox/methods_logitr.R[19:12]: quotes -- Only use double-quotes.
tests/spelling.R[1:20]: quotes -- Only use double-quotes.  
wch/r-source: +650 -0 violations
New violations (first 100):
share/R/examples-footer.R[5:67]: quotes -- Only use double-quotes.
share/R/examples-footer.R[12:5]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[143:37]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[146:16]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[147:16]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[148:16]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[150:37]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[153:16]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[154:16]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[155:16]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[159:33]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[161:12]: quotes -- Only use double-quotes.
src/gnuwin32/installer/JRins.R[162:12]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[115:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[123:51]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[124:20]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[130:21]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[131:18]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[160:32]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[161:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[162:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[166:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[167:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[186:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[196:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[197:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[198:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[199:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[207:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[209:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[210:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[219:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[220:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[221:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[222:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[223:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[224:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[225:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[234:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[237:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[238:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[244:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[247:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[248:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[251:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[252:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[262:0]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[265:30]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[270:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[275:27]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[278:20]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[282:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[286:27]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[289:20]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[293:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[326:8]: quotes -- Only use double-quotes.
src/gnuwin32/installer/WiXins.R[328:8]: quotes -- Only use double-quotes.
src/library/base/R/dates.R[128:29]: quotes -- Only use double-quotes.
src/library/base/R/datetime.R[450:25]: quotes -- Only use double-quotes.
src/library/base/R/factor.R[171:76]: quotes -- Only use double-quotes.
src/library/base/R/format.R[379:30]: quotes -- Only use double-quotes.
src/library/base/R/format.R[427:33]: quotes -- Only use double-quotes.
src/library/base/R/format.R[428:28]: quotes -- Only use double-quotes.
src/library/base/R/format.R[429:24]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[183:18]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[227:23]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[227:40]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[227:58]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[235:30]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[259:26]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[260:57]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[262:26]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[262:53]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[263:26]: quotes -- Only use double-quotes.
src/library/base/R/grep.R[263:55]: quotes -- Only use double-quotes.
src/library/base/R/namespace.R[659:33]: quotes -- Only use double-quotes.
src/library/base/R/namespace.R[662:26]: quotes -- Only use double-quotes.
src/library/base/R/namespace.R[673:26]: quotes -- Only use double-quotes.
src/library/base/R/traceback.R[35:35]: quotes -- Only use double-quotes.
src/library/base/R/traceback.R[40:29]: quotes -- Only use double-quotes.
src/library/base/R/traceback.R[42:25]: quotes -- Only use double-quotes.
src/library/base/R/traceback.R[66:31]: quotes -- Only use double-quotes.
src/library/base/R/zzz.R[692:39]: quotes -- Only use double-quotes.
src/library/base/R/zzz.R[694:14]: quotes -- Only use double-quotes.
src/library/base/R/zzz.R[694:41]: quotes -- Only use double-quotes.
src/library/base/demo/is.things.R[42:46]: quotes -- Only use double-quotes.
src/library/base/demo/is.things.R[44:47]: quotes -- Only use double-quotes.
src/library/compiler/R/cmp.R[2500:19]: quotes -- Only use double-quotes.
src/library/grDevices/R/convertColor.R[144:10]: quotes -- Only use double-quotes.
src/library/grDevices/R/unix/quartz.R[154:37]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[6:19]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[6:27]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[10:26]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[10:34]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[13:7]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[22:60]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[32:4]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[32:17]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[33:7]: quotes -- Only use double-quotes.
src/library/grDevices/tests/convertColor-tests.R[39:51]: quotes -- Only use double-quotes.  

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Benchmark on real-projects

Repository Avg. duration (main, seconds) Avg. duration (PR, seconds) PR - main PR - main (%) Number of iterations
easystats/datawizard 0.2039435 0.2022805 -0.0016629984 -0.8154213 50
lrberge/stringmagic 0.1841498 0.1884436 0.0042937951 2.3316857 50
pola-rs/r-polars 0.2575704 0.2597965 0.0022261714 0.8642964 50
Rdatatable/data.table 0.2342992 0.2429970 0.0086978391 3.7122785 50
ropensci/targets 0.4166986 0.4174080 0.0007093523 0.1702315 50
rstudio/shiny 0.2145088 0.2252703 0.0107614813 5.0168021 50
tidyverse/dplyr 0.2493478 0.2502057 0.0008578468 0.3440362 50
tidyverse/ggplot2 0.3818523 0.3838364 0.0019840818 0.5195940 50
vincentarelbundock/marginaleffects 0.2150054 0.2138907 -0.0011147048 -0.5184543 50
wch/r-source 1.8813200 1.8931093 0.0117892816 0.6266494 50

Copy link
Owner

@etiennebacher etiennebacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do a proper review later but just a few quick comments below. Also, it's worth keeping in mind that this feature might land in Air (posit-dev/air#231) (this is not actionable, just good to know).

///
/// ## Why is this bad?
///
/// Using a consistent quote delimiter improves readability.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth mentioning here that single and double quotes are interchangeable and this rule really is only related to readability. You could also justify that double quotes are preferred with those links:

expect_no_lint_with_settings("foo", "quotes", None, settings.clone());
expect_no_lint_with_settings("'blah'", "quotes", None, settings.clone());
expect_no_lint_with_settings("'\"bar\"'", "quotes", None, settings.clone());
expect_no_lint_with_settings("\"'blah\"", "quotes", None, settings.clone());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
expect_no_lint_with_settings("\"'blah\"", "quotes", None, settings.clone());
expect_no_lint_with_settings("\"'blah'\"", "quotes", None, settings.clone());

I think this R code isn't valid otherwise. Also isn't this line duplicated two lines below?

/// Use `quote` to choose the preferred quote delimiter for string
/// literals. Valid values are `"double"` (default) and `"single"`.
#[serde(rename = "quotes")]
pub quotes: Option<QuotesOptions>,
Copy link
Owner

@etiennebacher etiennebacher Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be named quote I think? If not, the comment above needs to be updated

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually quotes seems fine, just need to fix the `quote` in the docs.

Copy link
Owner

@etiennebacher etiennebacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really great, nice one! I kinda wish this was in Air so it can fix my quotes when I save the file, but it's already nice to have it here.


A few more comments:

  • in this example, the message "use double-quotes only" is ambiguous because it could also be related to the \' (but it's not):

     --> test.R:3:1
      |
    3 | '\'a'
      | ----- Only use double-quotes.
      |
    

    Can we improve the message a bit? Like Use double quotes to start and end a string? I'm really not sure this is better, so open to alternatives.

  • maybe it's worth reporting unnecessarily escaped quote, such as "\'a" that could simply be "'a". I don't know if there's a risk of false positives, we'd need to see ecosystem results for that. This doesn't have to be done in this PR, it's just a suggestion for an extension.

Comment on lines +96 to +101
// Allow the non-preferred quote when escaping would be needed
// eg. 'R says "Hello world" ...'` vs `"R says \"Hello world\" ..."`
// Skip cases in raw strings where using preferred quote reduces readability
// e.g. `'r("rawstring")'` vs `"r("rawstring")"`.
// Also skips cases where switching to the preferred quote results in invalid syntax
// e.g. r'(abc)"def)' becomes `r"(abc)"def)"`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all good examples, it would be useful to show them in the docs above.

/// Use `quote` to choose the preferred quote delimiter for string
/// literals. Valid values are `"double"` (default) and `"single"`.
#[serde(rename = "quotes")]
pub quotes: Option<QuotesOptions>,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually quotes seems fine, just need to fix the `quote` in the docs.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already tested in unit tests in quotes/mod.rs. Integration tests should only check TOML args (as you do in toml_rule_args.rs). You can remove this file.

@etiennebacher
Copy link
Owner

I also forgot to mention that you should update docs/config.md to add documentation on the quote parameter in TOML (see the section "Rule-specific arguments").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants