* bug#62696: python.el: Extra indentation for conditionals @ 2023-04-06 12:47 Gustaf Waldemarson 2023-04-09 12:11 ` kobarity 0 siblings, 1 reply; 14+ messages in thread From: Gustaf Waldemarson @ 2023-04-06 12:47 UTC (permalink / raw) To: 62696 [-- Attachment #1.1: Type: text/plain, Size: 15629 bytes --] Hello, The follow can be considered either a feature request or a bug and was originally asked as question on the Emacs StackOverflow page: < https://emacs.stackexchange.com/questions/76257/python-mode-multi-line-conditional-indentation > But I'll reproduce it in full here anyways: Given the following somewhat silly Python code with a multi-line condition: if ("VALUE" in my_uncessarily_long_dictionary and some_other_long_condition_case): do_something() else: pass This is written as Emacs typically indents each line, which I'm normally fine with. However, quite a few linters prefer the condition to be indented visually different from the next (non-conditional) line, e.g., something like this: if ("VALUE" in my_uncessarily_long_dictionary and some_other_long_condition_case): do_something(): else: pass As was helpfully provided by Tobias in the answer to this question on StackOverflow, this was solved on Emacs-28.1. I went ahead and refactored and tested it on Emacs-master and it appears to be working fine there as well. The code for this is attached to this email. One noticeable caveat is that **any** parenthesis can now be additionally indented, e.g., the follow is now also possible: this_is_a_tuple = (long_variable_name_here, also_a_long_variable_name) Although, given that this can be cycled at will by the user, I'm not sure if it is a bad additional feature or not. Ideally, I suppose that `python-indent-context` could be modified to add a `:inside-cond-paren` symbol that signals that the parenthesis is for a conditional expression and thus the extra indentation should be applied, and not in any other case. That does seem a bit harder for me to fix at a cursory glance however, so maybe this fix is enough? Best regards, Gustaf In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.33, cairo version 1.16.0) of 2023-03-26 built on ShadowX Repository revision: 248aabd9514c9eb21f4aa2e9062f8ce927d9fe54 Repository branch: master System Description: Ubuntu 22.04.2 LTS Configured using: 'configure --prefix=/home/xaldew/.local '--program-transform-name=s/^ctags$/ctags.emacs/' --without-makeinfo --with-xpm=ifavailable --with-jpeg=ifavailable --with-gif=ifavailable --with-tiff=ifavailable' Configured features: CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG LCMS2 LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB Important settings: value of $LANG: sv_SE.UTF-8 value of $XMODIFIERS: @im=ibus locale-coding-system: utf-8-unix Major mode: Magit Minor modes in effect: pyvenv-mode: t dap-tooltip-mode: t dap-ui-many-windows-mode: t dap-ui-controls-mode: t dap-ui-mode: t gdb-many-windows: t treemacs-filewatch-mode: t treemacs-follow-mode: t treemacs-git-mode: t treemacs-fringe-indicator-mode: t dap-auto-configure-mode: t dap-mode: t global-git-commit-mode: t magit-auto-revert-mode: t shell-dirtrack-mode: t beacon-mode: t server-mode: t hes-mode: t projectile-mode: t global-display-fill-column-indicator-mode: t global-display-line-numbers-mode: t global-so-long-mode: t yas-global-mode: t yas-minor-mode: t global-company-mode: t company-mode: t global-undo-tree-mode: t undo-tree-mode: t global-anzu-mode: t anzu-mode: t global-atomic-chrome-edit-mode: t windmove-mode: t which-key-mode: t anyclip-mode: t override-global-mode: t electric-pair-mode: t save-place-mode: t global-subword-mode: t subword-mode: t winner-mode: t global-auto-revert-mode: t xterm-mouse-mode: t savehist-mode: t ido-everywhere: t tooltip-mode: t global-eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t buffer-read-only: t column-number-mode: t line-number-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: /home/xaldew/.config/emacs/elpa/transient-20230315.1520/transient hides /home/xaldew/.local/share/emacs/30.0.50/lisp/transient Features: (shadow sort bbdb-message mail-extr warnings emacsbug cdlatex reftex reftex-loaddefs reftex-vars org-element org-persist org-id org-refile avl-tree oc-basic ol-eww eww xdg url-queue mm-url ol-rmail ol-mhe ol-irc ol-info ol-gnus nnselect gnus-art mm-uu mml2015 mm-view mml-smime smime dig gnus-sum shr pixel-fill kinsoku url-file svg gnus-group gnus-undo gnus-start gnus-dbus dbus gnus-cloud nnimap nnmail mail-source utf7 nnoo gnus-spec gnus-int gnus-range gnus-win gnus nnheader range ol-docview doc-view jka-compr ol-bibtex bibtex ol-bbdb ol-w3m org-tempo tempo cus-start ob-latex ob-plantuml ob-org ob-shell ob-gnuplot ob-C ob-python ob-ditaa ob-dot org ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-src ob-comint org-pcomplete org-list org-footnote org-faces org-entities ob-emacs-lisp ob-core ob-eval org-cycle org-table ol org-fold org-fold-core org-keys oc org-loaddefs cal-menu calendar cal-loaddefs org-version org-compat org-macs shortdoc help-fns radix-tree magit-annex magit-patch magit-subtree magit-gitignore magit-ediff ediff ediff-merg ediff-mult ediff-wind ediff-diff ediff-help ediff-init ediff-util image-mode exif guess-language pyvenv eshell esh-cmd esh-ext esh-opt esh-proc esh-io esh-arg esh-module esh-groups esh-util highlight-indentation anaconda-mode pythonic tramp tramp-loaddefs trampver tramp-integration files-x tramp-compat parse-time iso8601 ls-lisp python-mode/.yas-setup.el dap-python python treesit c++-genostream cmake-mode rst ace-window all-the-icons all-the-icons-faces data-material data-weathericons data-octicons data-fileicons data-faicons data-alltheicons vc-hg vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs log-view vc bug-reference misearch multi-isearch lsp-diagnostics lsp-headerline lsp-icons lsp-modeline dap-mouse dap-ui gdb-mi bui bui-list bui-info bui-entry bui-core bui-history bui-button bui-utils lsp-lens vc-git vc-dispatcher modern-cpp-font-lock .yas-setup.el cc-mode/.yas-setup.el view lsp-zig lsp-tilt lsp-steep lsp-svelte lsp-sqls lsp-ruby-syntax-tree lsp-ruby-lsp lsp-yaml lsp-xml lsp-vimscript lsp-vhdl lsp-volar lsp-vetur lsp-html lsp-verilog lsp-vala lsp-v lsp-typeprof lsp-ttcn3 lsp-toml lsp-terraform lsp-tex lsp-sorbet lsp-solargraph lsp-rust lsp-rf lsp-ruff-lsp lsp-remark lsp-racket lsp-r lsp-purescript lsp-pylsp lsp-pyls lsp-pwsh lsp-php lsp-pls lsp-perlnavigator lsp-perl lsp-openscad lsp-ocaml lsp-magik lsp-nix lsp-nim lsp-nginx lsp-mint lsp-marksman lsp-markdown lsp-lua lsp-ltex lsp-kotlin lsp-json lsp-javascript lsp-idris lsp-haxe lsp-groovy lsp-hack lsp-graphql lsp-gleam lsp-go lsp-completion lsp-gdscript lsp-fsharp lsp-fortran lsp-eslint lsp-erlang lsp-emmet lsp-elixir lsp-elm lsp-dockerfile lsp-dhall lsp-d lsp-css lsp-csharp gnutls lsp-crystal lsp-cmake lsp-clojure lsp-treemacs lsp-treemacs-generic lsp-treemacs-themes treemacs-treelib treemacs treemacs-header-line treemacs-compatibility treemacs-mode treemacs-interface treemacs-persistence treemacs-filewatch-mode treemacs-follow-mode treemacs-rendering treemacs-annotations treemacs-async treemacs-workspaces treemacs-dom treemacs-visuals treemacs-fringe-indicator treemacs-scope pulse treemacs-faces treemacs-icons treemacs-themes treemacs-core-utils pfuture hl-line treemacs-logging treemacs-customization treemacs-macros lsp-semantic-tokens lsp-clangd lsp-beancount lsp-bash lsp-astro lsp-ansible lsp-angular lsp-ada lsp-actionscript dap-gdb-lldb dap-utils dom xml dap-mode dap-tasks dap-launch lsp-docker yaml posframe dap-overlays magit-extras magit-submodule magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit magit-sequence magit-notes magit-worktree magit-tag magit-merge magit-branch magit-reset magit-files magit-refs magit-status magit magit-repos magit-apply magit-wip magit-log which-func magit-diff smerge-mode diff-mode git-commit log-edit message sendmail yank-media rfc822 mml mml-sec epa derived gnus-util time-date mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils mailheader pcvs-util add-log magit-core magit-autorevert magit-margin magit-transient magit-process with-editor shell pcomplete magit-mode transient magit-git magit-base magit-section format-spec crm compat dired-aux dired dired-loaddefs term/tmux term/xterm xterm pinentry beacon server form-feed paredit nameless flyspell ispell whitespace rainbow-delimiters highlight-escape-sequences projectile lisp-mnt grep ibuf-ext ibuffer ibuffer-loaddefs lsp-ui lsp-ui-flycheck lsp-ui-doc goto-addr lsp-ui-imenu lsp-ui-peek lsp-ui-sideline flycheck lsp-mode tree-widget spinner network-stream puny nsm markdown-mode noutline outline inline imenu f f-shortdoc ewoc epg rfc6068 epg-config compile text-property-search lsp-ui-util face-remap find-func lsp-protocol s ht dash display-fill-column-indicator display-line-numbers so-long py-snippets yasnippet-radical-snippets yasnippet-snippets yasnippet company-oddmuse company-keywords company-etags etags fileloop generator xref project company-gtags company-dabbrev-code company-dabbrev company-files company-clang company-capf company-cmake company-semantic company-template company-bbdb company undo-tree diff queue anzu thingatpt atomic-chrome websocket bindat let-alist color-theme-approximate advice color delim-col hydra-examples windmove rect hydra lv bbdb bbdb-site timezone cus-edit pp cus-load icons wid-edit ace-link avy which-key anyclip-mode cl-extra help-mode edmacro kmacro diminish use-package use-package-ensure use-package-delight use-package-diminish use-package-bind-key bind-key easy-mmode use-package-core finder-inf local-autoloads cwarn cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs elec-pair saveplace cap-words superword subword winner autorevert filenotify xt-mouse tango-dark-theme savehist ido gud comint ansi-osc ansi-color ring keybinds terminals ivy-autoloads spacemacs-theme-autoloads ace-link-autoloads kotlin-mode-autoloads company-auctex-autoloads gl-conf-mode-autoloads css-eldoc-autoloads beacon-autoloads lsp-ltex-autoloads paredit-autoloads glsl-mode-autoloads highlight-escape-sequences-autoloads powershell-autoloads gnuplot-mode-autoloads cuda-mode-autoloads ein-autoloads request-autoloads ssh-config-mode-autoloads git-modes-autoloads mmm-mode-autoloads ebdb-autoloads rmsbolt-autoloads debbugs-autoloads dart-mode-autoloads sublime-themes-autoloads coffee-mode-autoloads graphviz-dot-mode-autoloads magit-annex-autoloads opencl-mode-autoloads json-mode-autoloads rx company-anaconda-autoloads pinentry-autoloads rainbow-mode-autoloads htmlize-autoloads projectile-autoloads flycheck-rust-autoloads bbdb-vcard-autoloads jira-markup-mode-autoloads browse-kill-ring-autoloads helm-dash-autoloads sx-autoloads jenkins-autoloads smart-jump-autoloads bbdb-autoloads which-key-autoloads anzu-autoloads x86-lookup-autoloads cmake-mode-autoloads flycheck-kotlin-autoloads undo-tree-autoloads rust-mode-autoloads plantuml-mode-autoloads magit-gerrit-autoloads lua-mode-autoloads yaml-mode-autoloads evil-autoloads deferred-autoloads iedit-autoloads unfill-autoloads srefactor-autoloads abc-mode-autoloads autoinsert solarized-theme-autoloads alert-autoloads gntp-autoloads emms-autoloads cider-autoloads sesman-autoloads queue-autoloads parseedn-autoloads parseclj-autoloads clojure-mode-autoloads flycheck-package-autoloads package-lint-autoloads atomic-chrome-autoloads websocket-autoloads powerthesaurus-autoloads jeison-autoloads dash-docs-autoloads rainbow-delimiters-autoloads form-feed-autoloads yasnippet-radical-snippets-autoloads pyimport-autoloads shut-up-autoloads json-snatcher-autoloads helm-lsp-autoloads helm-autoloads clang-format-autoloads poly-markdown-autoloads polymode-autoloads toml-mode-autoloads diminish-autoloads cdlatex-autoloads eclim-autoloads anaphora-autoloads py-snippets-autoloads yasnippet-snippets-autoloads zenburn-theme-autoloads dap-mode-autoloads lsp-docker-autoloads lsp-treemacs-autoloads treemacs-autoloads cfrs-autoloads posframe-autoloads pfuture-autoloads ace-window-autoloads avy-autoloads bui-autoloads magit-svn-autoloads magit-autoloads pcase git-commit-autoloads with-editor-autoloads transient-autoloads go-mode-autoloads goto-chg-autoloads log4e-autoloads color-theme-approximate-autoloads cargo-autoloads calfw-autoloads company-quickhelp-autoloads helm-core-autoloads async-autoloads ecb-autoloads modern-cpp-font-lock-autoloads dts-mode-autoloads nov-autoloads esxml-autoloads kv-autoloads company-math-autoloads math-symbol-lists-autoloads elpy-autoloads pyvenv-autoloads highlight-indentation-autoloads ob-ipython-autoloads dash-functional-autoloads hydra-autoloads auto-complete-auctex-autoloads auto-complete-autoloads yasnippet-autoloads auctex-latexmk-autoloads auctex-autoloads tex-site yaml-autoloads ahk-mode-autoloads magit-section-autoloads compat-autoloads cask-mode-autoloads company-c-headers-autoloads company-autoloads csv-mode-autoloads gnuplot-autoloads anaconda-mode-autoloads pythonic-autoloads pos-tip-autoloads zerodark-theme-autoloads all-the-icons-autoloads image+-autoloads expand-region-autoloads gnus-desktop-notify-autoloads flycheck-autoloads pkg-info-autoloads epl-autoloads ggtags-autoloads web-mode-autoloads lsp-ui-autoloads lsp-mode-autoloads lv-autoloads markdown-mode-autoloads spinner-autoloads ht-autoloads f-autoloads uimage-autoloads guess-language-autoloads dumb-jump-autoloads popup-autoloads dash-autoloads s-autoloads google-c-style-autoloads nameless-autoloads info slime-autoloads macrostep-autoloads package browse-url url url-proxy url-privacy url-expand url-methods url-history url-cookie generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic indonesian philippine cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp files window text-properties overlay sha1 md5 base64 format env code-pages mule custom widget keymap hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty make-network-process emacs) Memory information: ((conses 16 817895 212638) (symbols 48 62999 0) (strings 32 249530 19612) (string-bytes 1 8101995) (vectors 16 160320) (vector-slots 8 3855694 143961) (floats 8 1381 10031) (intervals 56 21064 2868) (buffers 976 49)) [-- Attachment #1.2: Type: text/html, Size: 16950 bytes --] [-- Attachment #2: 0001-Allow-indent-in-long-python-mode-conditionals.patch --] [-- Type: text/x-patch, Size: 1538 bytes --] From 8dc2e7275d68d2749822b59e4748794ab27621c5 Mon Sep 17 00:00:00 2001 From: Gustaf Waldemarson <gustaf.waldemarson@gmail.com> Date: Tue, 4 Apr 2023 14:04:44 +0200 Subject: [PATCH] Allow indent in long python-mode conditionals. * lisp/progmodes/python.el: Allow additional indentation in parentheses to more easily satisfy various Python linters. --- lisp/progmodes/python.el | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bbabce80b4d..d7c6a9218c7 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1248,6 +1248,11 @@ python-indent-offset :type 'integer :safe 'integerp) +(defcustom python-indent-add-after-paren python-indent-offset + "Additional indent after paren." + :type 'number + :group 'python) + (defcustom python-indent-guess-indent-offset t "Non-nil tells Python mode to guess `python-indent-offset' value." :type 'boolean @@ -1580,7 +1585,10 @@ python-indent--calculate-indentation ;; Add one level to avoid same indent as next logical line. (+ column python-indent-offset) column))) - (`(,(or :inside-paren + (`(:inside-paren . ,start) + (goto-char start) + (+ (current-column) python-indent-add-after-paren)) + (`(,(or :after-backslash-block-continuation :after-backslash-dotted-continuation) . ,start) ;; Use the column given by the context. (goto-char start) -- 2.34.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-06 12:47 bug#62696: python.el: Extra indentation for conditionals Gustaf Waldemarson @ 2023-04-09 12:11 ` kobarity 2023-04-10 11:11 ` Gustaf Waldemarson 0 siblings, 1 reply; 14+ messages in thread From: kobarity @ 2023-04-09 12:11 UTC (permalink / raw) To: Gustaf Waldemarson; +Cc: 62696 [-- Attachment #1: Type: text/plain, Size: 3323 bytes --] Gustaf Waldemarson wrote: > One noticeable caveat is that **any** parenthesis can now be additionally > indented, e.g., the follow is now also possible: > > this_is_a_tuple = (long_variable_name_here, > also_a_long_variable_name) > > Although, given that this can be cycled at will by the user, I'm not sure if it > is a bad additional feature or not. > > Ideally, I suppose that `python-indent-context` could be modified to add a > `:inside-cond-paren` symbol that signals that the parenthesis is for a > conditional expression and thus the extra indentation should be applied, and not > in any other case. That does seem a bit harder for me to fix at a cursory glance > however, so maybe this fix is enough? Hi Gustaf, I agree with you in that it's better to have a new indent context, and I tried to implement it. At first, I thought that it would be enough to add a counterpart of the user option `python-indent-def-block-scale' and corresponding `:inside-paren-newline-start-from-block' context. `python-indent-def-block-scale' can be used to customize the following code #+begin_src python if ( "VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case ): do_something() #+end_src to be indented as follows (with a TAB at "):" line): #+begin_src python if ( "VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case ): do_something() #+end_src This is the style used by the popular formatter "black". From the name `python-indent-def-block-scale' and its docstring, it is easy to assume that it only works for def block, but in fact it works for every blocks. As `python-indent-def-block-scale' works only when there is no item on the same line following the opening paren, I tried to add a similar user option and an indent context for the opening paren followed by some items on the same line. It could indent as follows: #+begin_src python if ("VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case): do_something() #+end_src However, it could not handle correctly the following example: #+begin_src python elif (some_case or another_case): do_another() #+end_src The extra indentation is not needed here. So I think it is best to increase the indentation only if the calculated indentation equals to the indentation of the contents of the block ("do_something()" in the above example). This is similar to the way I fixed Bug#57262. Unlike Bug#57262, the current indentation shown below is not a violation of the latest PEP8: #+begin_src python if ("VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case): do_something() #+end_src Although pycodestyle reports E129 "visually indented line with same indent as next logical line," PEP8 was changed to allow this. This is explained in the following issue, for example: https://github.com/PyCQA/pycodestyle/issues/474 So changing this indentation should be a user option. Attached is my implementation of this. The user option `python-indent-block-paren-deeper' is added to customize this indentation. I would be glad if you could try it. [-- Attachment #2: 0001-Add-a-new-user-option-in-Python-mode-to-improve-the-.patch --] [-- Type: application/octet-stream, Size: 11074 bytes --] From acec03331413b621843fb1489e9aeb6db927614a Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Sun, 9 Apr 2023 20:48:00 +0900 Subject: [PATCH] Add a new user option in Python mode to improve the indentation * lisp/progmodes/python.el (python-indent-block-paren-deeper): New user option. (python-indent-context): Add a new context :inside-paren-from-block. (python-indent--calculate-indentation): Modify according to `python-indent-block-paren-deeper' and :inside-paren-from-block. * test/lisp/progmodes/python-tests.el (python-indent-inside-paren-block-1) (python-indent-inside-paren-block-2) (python-indent-inside-paren-block-3) (python-indent-inside-paren-block-4): New tests. (python-indent-inside-paren-5, python-indent-dedenters-8): Modify according to the new context. * etc/NEWS: Document the new user option. (Bug#62696) --- etc/NEWS | 8 ++ lisp/progmodes/python.el | 43 +++++++++-- test/lisp/progmodes/python-tests.el | 116 +++++++++++++++++++++++++++- 3 files changed, 158 insertions(+), 9 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index d20d9f65ac9..61736e8edf4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -261,6 +261,14 @@ When non-nil, it will automatically register every package as a project, that you can quickly select using 'project-switch-project' ('C-x p p'). +** Python mode + +*** New user option 'python-indent-block-paren-deeper'. +If this variable is set to non-nil, and some items follow the opening +paren on the same line in a block statement, and the calculated +indentation of a line inside the parens equals to the indentation of +the block contents, the indentation level of the line is increased. + \f * New Modes and Packages in Emacs 30.1 diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bbabce80b4d..dbc48038554 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1270,6 +1270,17 @@ python-indent-def-block-scale :type 'integer :safe 'natnump) +(defcustom python-indent-block-paren-deeper nil + "Non-nil means to increase indentation inside parens of a block. +If this variable is set to non-nil, and some items follow the +opening paren on the same line in a block statement, and the +calculated indentation of a line inside the parens equals to the +indentation of the block contents, the indentation level of the +line is increased." + :version "30.1" + :type 'boolean + :safe 'booleanp) + (defvar python-indent-current-level 0 "Deprecated var available for compatibility.") @@ -1367,6 +1378,10 @@ python-indent-context - Point is inside a paren with items starting in their own line from a block start. - START is the position of the open paren. +:inside-paren-from-block + - Point is inside a paren from a block start followed by some + items on the same line. + - START is the first non space char position *after* the open paren. :after-backslash - Fallback case when point is after backslash. @@ -1450,12 +1465,16 @@ python-indent-context (starts-in-newline (cons :inside-paren-newline-start start)) ;; General case. - (t (cons :inside-paren - (save-excursion - (goto-char (1+ start)) - (skip-syntax-forward "(" 1) - (skip-syntax-forward " ") - (point)))))))) + (t (let ((after-start (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "(" 1) + (skip-syntax-forward " ") + (point)))) + (if (save-excursion + (python-nav-beginning-of-statement) + (python-info-looking-at-beginning-of-block)) + (cons :inside-paren-from-block after-start) + (cons :inside-paren after-start)))))))) ;; After backslash. ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) (python-info-line-ends-backslash-p @@ -1603,7 +1622,17 @@ python-indent--calculate-indentation (`(,(or :inside-paren-newline-start-from-block) . ,start) (goto-char start) (+ (current-indentation) - (* python-indent-offset python-indent-def-block-scale)))))) + (* python-indent-offset python-indent-def-block-scale))) + (`(,:inside-paren-from-block . ,start) + (goto-char start) + (let ((column (current-column))) + (if (and python-indent-block-paren-deeper + (= column (+ (save-excursion + (python-nav-beginning-of-statement) + (current-indentation)) + python-indent-offset))) + (+ column python-indent-offset) + column)))))) (defun python-indent--calculate-levels (indentation) "Calculate levels list given INDENTATION. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 50153e66da5..60b11d572cf 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -1139,7 +1139,7 @@ python-indent-inside-paren-5 (should (eq (car (python-indent-context)) :no-indent)) (should (= (python-indent-calculate-indentation) 0)) (forward-line 1) - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 7)) (forward-line 1) (should (eq (car (python-indent-context)) :after-block-start)) @@ -1174,6 +1174,118 @@ python-indent-inside-paren-7 ;; This signals an error if the test fails (should (eq (car (python-indent-context)) :inside-paren-newline-start)))) +(ert-deftest python-indent-inside-paren-block-1 () + "`python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-2 () + "`python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + +(ert-deftest python-indent-inside-paren-block-3 () + "With backslash. `python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-4 () + "With backslash. `python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + (ert-deftest python-indent-after-block-1 () "The most simple after-block case that shouldn't fail." (python-tests-with-temp-buffer @@ -1670,7 +1782,7 @@ python-indent-dedenters-8 (should (= (python-indent-calculate-indentation) 0)) (should (= (python-indent-calculate-indentation t) 0)) (python-tests-look-at "a == 4):\n") - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 6)) (python-indent-line) (should (= (python-indent-calculate-indentation t) 4)) -- 2.34.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-09 12:11 ` kobarity @ 2023-04-10 11:11 ` Gustaf Waldemarson 2023-04-10 15:21 ` kobarity 0 siblings, 1 reply; 14+ messages in thread From: Gustaf Waldemarson @ 2023-04-10 11:11 UTC (permalink / raw) To: kobarity; +Cc: 62696 [-- Attachment #1: Type: text/plain, Size: 3991 bytes --] Hello! Thanks a lot for this! I had no idea that they had changed the relevant PEPs to account for this, but as mentioned it is still a good idea to have the option to change this depending on your preference. And as far as I have been able to tell from coding with this patch for a few hours, it seems to work beautifully and I would love to see this as an official feature! Best regards, Gustaf Den sön 9 apr. 2023 kl 14:11 skrev kobarity <kobarity@gmail.com>: > > Gustaf Waldemarson wrote: > > One noticeable caveat is that **any** parenthesis can now be additionally > > indented, e.g., the follow is now also possible: > > > > this_is_a_tuple = (long_variable_name_here, > > also_a_long_variable_name) > > > > Although, given that this can be cycled at will by the user, I'm not > sure if it > > is a bad additional feature or not. > > > > Ideally, I suppose that `python-indent-context` could be modified to add > a > > `:inside-cond-paren` symbol that signals that the parenthesis is for a > > conditional expression and thus the extra indentation should be applied, > and not > > in any other case. That does seem a bit harder for me to fix at a > cursory glance > > however, so maybe this fix is enough? > > Hi Gustaf, > > I agree with you in that it's better to have a new indent context, and > I tried to implement it. > > At first, I thought that it would be enough to add a counterpart of > the user option `python-indent-def-block-scale' and corresponding > `:inside-paren-newline-start-from-block' context. > `python-indent-def-block-scale' can be used to customize the following > code > > #+begin_src python > if ( > "VALUE" in my_unnecessarily_long_dictionary > and some_other_long_condition_case > ): > do_something() > #+end_src > > to be indented as follows (with a TAB at "):" line): > > #+begin_src python > if ( > "VALUE" in my_unnecessarily_long_dictionary > and some_other_long_condition_case > ): > do_something() > #+end_src > > This is the style used by the popular formatter "black". > > From the name `python-indent-def-block-scale' and its docstring, it is > easy to assume that it only works for def block, but in fact it works > for every blocks. As `python-indent-def-block-scale' works only when > there is no item on the same line following the opening paren, I tried > to add a similar user option and an indent context for the opening > paren followed by some items on the same line. It could indent as > follows: > > #+begin_src python > if ("VALUE" in my_unnecessarily_long_dictionary > and some_other_long_condition_case): > do_something() > #+end_src > > However, it could not handle correctly the following example: > > #+begin_src python > elif (some_case or > another_case): > do_another() > #+end_src > > The extra indentation is not needed here. > > So I think it is best to increase the indentation only if the > calculated indentation equals to the indentation of the contents of > the block ("do_something()" in the above example). This is similar to > the way I fixed Bug#57262. > > Unlike Bug#57262, the current indentation shown below is not a > violation of the latest PEP8: > > #+begin_src python > if ("VALUE" in my_unnecessarily_long_dictionary > and some_other_long_condition_case): > do_something() > #+end_src > > Although pycodestyle reports E129 "visually indented line with same > indent as next logical line," PEP8 was changed to allow this. This is > explained in the following issue, for example: > https://github.com/PyCQA/pycodestyle/issues/474 > > So changing this indentation should be a user option. Attached is my > implementation of this. The user option > `python-indent-block-paren-deeper' is added to customize this > indentation. I would be glad if you could try it. > [-- Attachment #2: Type: text/html, Size: 4884 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-10 11:11 ` Gustaf Waldemarson @ 2023-04-10 15:21 ` kobarity 2023-04-11 11:11 ` Gustaf Waldemarson 0 siblings, 1 reply; 14+ messages in thread From: kobarity @ 2023-04-10 15:21 UTC (permalink / raw) To: Gustaf Waldemarson; +Cc: 62696 Gustaf Waldemarson wrote: > Thanks a lot for this! I had no idea that they had changed the relevant PEPs to account > for this, but as mentioned it is still a good idea to have the option to change this depending > on your preference. And as far as I have been able to tell from coding with this patch for a > few hours, it seems to work beautifully and I would love to see this as an official feature! Hi Gustaf, Thank you for testing my patch. I am relieved that it seems to have fulfilled your request. As I am not a native English speaker, I welcome any feedback from anyone on the name and/or docstrings of the new user option as well as on the behavior and coding. ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-10 15:21 ` kobarity @ 2023-04-11 11:11 ` Gustaf Waldemarson 2023-04-12 15:26 ` kobarity 0 siblings, 1 reply; 14+ messages in thread From: Gustaf Waldemarson @ 2023-04-11 11:11 UTC (permalink / raw) To: kobarity; +Cc: 62696 [-- Attachment #1.1: Type: text/plain, Size: 1592 bytes --] Hello Kobarity, Being Swedish, I am hardly an authority on the English language. That said, I went ahead and double-checked the docstring and such, and the only thing that I found a bit confusing is the `python-indent-block-paren-deeper` description as follows: "Increase indentation inside parens of a block. When this variable is set to non-nil and the contents of a block inside parens are indented to the same level as outside the same block, increase the indentation of the line." This is really nitpicking though, and I may be using some terms incorrectly since since I don't know a lot of the internals here, so feel free to disregard any of this. These changes are also available in attached patch, feel free to use it if need be! Best regards, Gustaf Den mån 10 apr. 2023 kl 17:21 skrev kobarity <kobarity@gmail.com>: > > Gustaf Waldemarson wrote: > > Thanks a lot for this! I had no idea that they had changed the relevant > PEPs to account > > for this, but as mentioned it is still a good idea to have the option to > change this depending > > on your preference. And as far as I have been able to tell from coding > with this patch for a > > few hours, it seems to work beautifully and I would love to see this as > an official feature! > > Hi Gustaf, > > Thank you for testing my patch. I am relieved that it seems to have > fulfilled your request. > > As I am not a native English speaker, I welcome any feedback from > anyone on the name and/or docstrings of the new user option as well as > on the behavior and coding. > [-- Attachment #1.2: Type: text/html, Size: 2068 bytes --] [-- Attachment #2: 0001-Add-a-new-user-option-in-Python-mode-to-improve-indent-2.patch --] [-- Type: text/x-patch, Size: 10909 bytes --] From ea2de07164cee80a85226e68b83692d6eeda4f46 Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Sun, 9 Apr 2023 20:48:00 +0900 Subject: [PATCH] Add a new user option in Python mode to improve the indentation * lisp/progmodes/python.el (python-indent-block-paren-deeper): New user option. (python-indent-context): Add a new context :inside-paren-from-block. (python-indent--calculate-indentation): Modify according to `python-indent-block-paren-deeper' and :inside-paren-from-block. * test/lisp/progmodes/python-tests.el (python-indent-inside-paren-block-1) (python-indent-inside-paren-block-2) (python-indent-inside-paren-block-3) (python-indent-inside-paren-block-4): New tests. (python-indent-inside-paren-5, python-indent-dedenters-8): Modify according to the new context. * etc/NEWS: Document the new user option. (Bug#62696) --- etc/NEWS | 8 ++ lisp/progmodes/python.el | 41 ++++++++-- test/lisp/progmodes/python-tests.el | 116 +++++++++++++++++++++++++++- 3 files changed, 156 insertions(+), 9 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 5e1fd76e99e..1fd97c35208 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -266,6 +266,14 @@ When non-nil, it will automatically register every package as a project, that you can quickly select using 'project-switch-project' ('C-x p p'). +** Python mode + +*** New user option 'python-indent-block-paren-deeper'. +Increase indentation inside parens of a block. +When this variable is set to non-nil and the contents of a block +inside parens are indented to the same level as outside the same +block, increase the indentation of the line. + \f * New Modes and Packages in Emacs 30.1 diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bbabce80b4d..0868b77f201 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1270,6 +1270,15 @@ python-indent-def-block-scale :type 'integer :safe 'natnump) +(defcustom python-indent-block-paren-deeper nil + "Increase indentation inside parens of a block. +When this variable is set to non-nil and the contents of a block +inside parens are indented to the same level as outside the same +block, increase the indentation of the line." + :version "30.1" + :type 'boolean + :safe 'booleanp) + (defvar python-indent-current-level 0 "Deprecated var available for compatibility.") @@ -1367,6 +1376,10 @@ python-indent-context - Point is inside a paren with items starting in their own line from a block start. - START is the position of the open paren. +:inside-paren-from-block + - Point is inside a paren from a block start followed by some + items on the same line. + - START is the first non space char position *after* the open paren. :after-backslash - Fallback case when point is after backslash. @@ -1450,12 +1463,16 @@ python-indent-context (starts-in-newline (cons :inside-paren-newline-start start)) ;; General case. - (t (cons :inside-paren - (save-excursion - (goto-char (1+ start)) - (skip-syntax-forward "(" 1) - (skip-syntax-forward " ") - (point)))))))) + (t (let ((after-start (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "(" 1) + (skip-syntax-forward " ") + (point)))) + (if (save-excursion + (python-nav-beginning-of-statement) + (python-info-looking-at-beginning-of-block)) + (cons :inside-paren-from-block after-start) + (cons :inside-paren after-start)))))))) ;; After backslash. ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) (python-info-line-ends-backslash-p @@ -1603,7 +1620,17 @@ python-indent--calculate-indentation (`(,(or :inside-paren-newline-start-from-block) . ,start) (goto-char start) (+ (current-indentation) - (* python-indent-offset python-indent-def-block-scale)))))) + (* python-indent-offset python-indent-def-block-scale))) + (`(,:inside-paren-from-block . ,start) + (goto-char start) + (let ((column (current-column))) + (if (and python-indent-block-paren-deeper + (= column (+ (save-excursion + (python-nav-beginning-of-statement) + (current-indentation)) + python-indent-offset))) + (+ column python-indent-offset) + column)))))) (defun python-indent--calculate-levels (indentation) "Calculate levels list given INDENTATION. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 50153e66da5..60b11d572cf 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -1139,7 +1139,7 @@ python-indent-inside-paren-5 (should (eq (car (python-indent-context)) :no-indent)) (should (= (python-indent-calculate-indentation) 0)) (forward-line 1) - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 7)) (forward-line 1) (should (eq (car (python-indent-context)) :after-block-start)) @@ -1174,6 +1174,118 @@ python-indent-inside-paren-7 ;; This signals an error if the test fails (should (eq (car (python-indent-context)) :inside-paren-newline-start)))) +(ert-deftest python-indent-inside-paren-block-1 () + "`python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-2 () + "`python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + +(ert-deftest python-indent-inside-paren-block-3 () + "With backslash. `python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-4 () + "With backslash. `python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + (ert-deftest python-indent-after-block-1 () "The most simple after-block case that shouldn't fail." (python-tests-with-temp-buffer @@ -1670,7 +1782,7 @@ python-indent-dedenters-8 (should (= (python-indent-calculate-indentation) 0)) (should (= (python-indent-calculate-indentation t) 0)) (python-tests-look-at "a == 4):\n") - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 6)) (python-indent-line) (should (= (python-indent-calculate-indentation t) 4)) -- 2.25.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-11 11:11 ` Gustaf Waldemarson @ 2023-04-12 15:26 ` kobarity 2023-04-16 13:24 ` kobarity 0 siblings, 1 reply; 14+ messages in thread From: kobarity @ 2023-04-12 15:26 UTC (permalink / raw) To: Gustaf Waldemarson; +Cc: 62696 Gustaf Waldemarson wrote: > "Increase indentation inside parens of a block. > When this variable is set to non-nil and the contents of a block > inside parens are indented to the same level as outside the same > block, increase the indentation of the line." Hi Gustaf, Thank you for your suggestion. I think this is more readable and would like to make changes in this direction. Just to be clear, what I wanted to express by "some items follow the opening paren on the same line in a block statement" is that it only works with the code like the following: #+begin_src python if ("VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case): do_something() #+end_src And it does not work for the code like the following: #+begin_src python if ( "VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case): do_something() #+end_src This is intentional. Because this code is usually written as follows: #+begin_src python if ( "VALUE" in my_unnecessarily_long_dictionary and some_other_long_condition_case ): do_something() #+end_src In this case, there is no need for extra indentation. As I wrote in the previous mail, this case is processed by the existing code and can be customized with `python-indent-def-block-scale'. However, this may be a marginal difference. In any case, I will wait a few more days for other comments and hope to revise the patch over the weekend. Best regards, kobarity ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-12 15:26 ` kobarity @ 2023-04-16 13:24 ` kobarity 2023-04-16 15:49 ` Gustaf Waldemarson 0 siblings, 1 reply; 14+ messages in thread From: kobarity @ 2023-04-16 13:24 UTC (permalink / raw) To: Gustaf Waldemarson; +Cc: 62696 [-- Attachment #1: Type: text/plain, Size: 1237 bytes --] kobarity wrote: > Gustaf Waldemarson wrote: > > "Increase indentation inside parens of a block. > > When this variable is set to non-nil and the contents of a block > > inside parens are indented to the same level as outside the same > > block, increase the indentation of the line." > > Thank you for your suggestion. I think this is more readable and > would like to make changes in this direction. I have concluded that it's better to include an example in the docstring of `python-indent-block-paren-deeper'. How about the following? I also attached the updated patch. "Increase indentation inside parens of a block. If non-nil, increase the indentation of the lines inside parens in a header of a block when they are indented to the same level as the body of the block: if (some_expression and another_expression): do_something() instead of: if (some_expression and another_expression): do_something() This variable only works if the opening paren is followed by non-whitespace characters on the same line. Modify `python-indent-def-block-scale' to customize the case where non-whitespace character does not follow the opening paren on the same line." Best regards, kobarity [-- Attachment #2: 0001-Add-a-new-user-option-in-Python-mode-to-improve-the-.patch --] [-- Type: application/octet-stream, Size: 11489 bytes --] From 6bc15443e9f16b5bfd51254ab069afb20d9b21df Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Sun, 16 Apr 2023 22:18:39 +0900 Subject: [PATCH] Add a new user option in Python mode to improve the indentation * lisp/progmodes/python.el (python-indent-block-paren-deeper): New user option. (python-indent-context): Add a new context :inside-paren-from-block. (python-indent--calculate-indentation): Modify according to `python-indent-block-paren-deeper' and :inside-paren-from-block. * test/lisp/progmodes/python-tests.el (python-indent-inside-paren-block-1) (python-indent-inside-paren-block-2) (python-indent-inside-paren-block-3) (python-indent-inside-paren-block-4): New tests. (python-indent-inside-paren-5, python-indent-dedenters-8): Modify according to the new context. * etc/NEWS: Document the new user option. (Bug#62696) --- etc/NEWS | 17 ++++ lisp/progmodes/python.el | 57 ++++++++++++-- test/lisp/progmodes/python-tests.el | 116 +++++++++++++++++++++++++++- 3 files changed, 181 insertions(+), 9 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b121002b246..9e318812714 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -276,6 +276,23 @@ distracting and easily confused with actual code, or a significant early aid that relieves you from moving the buffer or reaching for the mouse to consult an error message. +** Python mode + +*** New user option 'python-indent-block-paren-deeper'. +If non-nil, increase the indentation of the lines inside parens in a +header of a block when they are indented to the same level as the body +of the block: + + if (some_expression + and another_expression): + do_something() + +instead of: + + if (some_expression + and another_expression): + do_something() + \f * New Modes and Packages in Emacs 30.1 diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bbabce80b4d..9ae95ecfc1c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1270,6 +1270,31 @@ python-indent-def-block-scale :type 'integer :safe 'natnump) +(defcustom python-indent-block-paren-deeper nil + "Increase indentation inside parens of a block. +If non-nil, increase the indentation of the lines inside parens +in a header of a block when they are indented to the same level +as the body of the block: + + if (some_expression + and another_expression): + do_something() + +instead of: + + if (some_expression + and another_expression): + do_something() + +This variable only works if the opening paren is followed by +non-whitespace characters on the same line. Modify +`python-indent-def-block-scale' to customize the case where +non-whitespace character does not follow the opening paren on the +same line." + :version "30.1" + :type 'boolean + :safe 'booleanp) + (defvar python-indent-current-level 0 "Deprecated var available for compatibility.") @@ -1367,6 +1392,10 @@ python-indent-context - Point is inside a paren with items starting in their own line from a block start. - START is the position of the open paren. +:inside-paren-from-block + - Point is inside a paren from a block start followed by some + items on the same line. + - START is the first non space char position *after* the open paren. :after-backslash - Fallback case when point is after backslash. @@ -1450,12 +1479,16 @@ python-indent-context (starts-in-newline (cons :inside-paren-newline-start start)) ;; General case. - (t (cons :inside-paren - (save-excursion - (goto-char (1+ start)) - (skip-syntax-forward "(" 1) - (skip-syntax-forward " ") - (point)))))))) + (t (let ((after-start (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "(" 1) + (skip-syntax-forward " ") + (point)))) + (if (save-excursion + (python-nav-beginning-of-statement) + (python-info-looking-at-beginning-of-block)) + (cons :inside-paren-from-block after-start) + (cons :inside-paren after-start)))))))) ;; After backslash. ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) (python-info-line-ends-backslash-p @@ -1603,7 +1636,17 @@ python-indent--calculate-indentation (`(,(or :inside-paren-newline-start-from-block) . ,start) (goto-char start) (+ (current-indentation) - (* python-indent-offset python-indent-def-block-scale)))))) + (* python-indent-offset python-indent-def-block-scale))) + (`(,:inside-paren-from-block . ,start) + (goto-char start) + (let ((column (current-column))) + (if (and python-indent-block-paren-deeper + (= column (+ (save-excursion + (python-nav-beginning-of-statement) + (current-indentation)) + python-indent-offset))) + (+ column python-indent-offset) + column)))))) (defun python-indent--calculate-levels (indentation) "Calculate levels list given INDENTATION. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 50153e66da5..60b11d572cf 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -1139,7 +1139,7 @@ python-indent-inside-paren-5 (should (eq (car (python-indent-context)) :no-indent)) (should (= (python-indent-calculate-indentation) 0)) (forward-line 1) - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 7)) (forward-line 1) (should (eq (car (python-indent-context)) :after-block-start)) @@ -1174,6 +1174,118 @@ python-indent-inside-paren-7 ;; This signals an error if the test fails (should (eq (car (python-indent-context)) :inside-paren-newline-start)))) +(ert-deftest python-indent-inside-paren-block-1 () + "`python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-2 () + "`python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + +(ert-deftest python-indent-inside-paren-block-3 () + "With backslash. `python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-4 () + "With backslash. `python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + (ert-deftest python-indent-after-block-1 () "The most simple after-block case that shouldn't fail." (python-tests-with-temp-buffer @@ -1670,7 +1782,7 @@ python-indent-dedenters-8 (should (= (python-indent-calculate-indentation) 0)) (should (= (python-indent-calculate-indentation t) 0)) (python-tests-look-at "a == 4):\n") - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 6)) (python-indent-line) (should (= (python-indent-calculate-indentation t) 4)) -- 2.34.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-16 13:24 ` kobarity @ 2023-04-16 15:49 ` Gustaf Waldemarson 2023-04-18 14:23 ` kobarity 0 siblings, 1 reply; 14+ messages in thread From: Gustaf Waldemarson @ 2023-04-16 15:49 UTC (permalink / raw) To: kobarity; +Cc: 62696 [-- Attachment #1: Type: text/plain, Size: 1660 bytes --] Hello, I think that's a really good idea actually. It might also be a good idea to add a negative example (i.e., the black-indentation style you mentioned earlier), or a reference to one (maybe to the tests?) Best regards, Gustaf Den sön 16 apr. 2023 kl 15:24 skrev kobarity <kobarity@gmail.com>: > > kobarity wrote: > > Gustaf Waldemarson wrote: > > > "Increase indentation inside parens of a block. > > > When this variable is set to non-nil and the contents of a block > > > inside parens are indented to the same level as outside the same > > > block, increase the indentation of the line." > > > > Thank you for your suggestion. I think this is more readable and > > would like to make changes in this direction. > > I have concluded that it's better to include an example in the > docstring of `python-indent-block-paren-deeper'. How about the > following? I also attached the updated patch. > > "Increase indentation inside parens of a block. > If non-nil, increase the indentation of the lines inside parens > in a header of a block when they are indented to the same level > as the body of the block: > > if (some_expression > and another_expression): > do_something() > > instead of: > > if (some_expression > and another_expression): > do_something() > > This variable only works if the opening paren is followed by > non-whitespace characters on the same line. Modify > `python-indent-def-block-scale' to customize the case where > non-whitespace character does not follow the opening paren on the > same line." > > Best regards, > kobarity > [-- Attachment #2: Type: text/html, Size: 2206 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-16 15:49 ` Gustaf Waldemarson @ 2023-04-18 14:23 ` kobarity 2023-04-20 8:22 ` Eli Zaretskii 0 siblings, 1 reply; 14+ messages in thread From: kobarity @ 2023-04-18 14:23 UTC (permalink / raw) To: Gustaf Waldemarson; +Cc: 62696, Dmitry Gutov, Ross Donaldson, Noam Postavsky [-- Attachment #1: Type: text/plain, Size: 1493 bytes --] Gustaf Waldemarson wrote: > I think that's a really good idea actually. It might also be a good idea to add a > negative example (i.e., the black-indentation style you mentioned earlier), or > a reference to one (maybe to the tests?) I think the best way is to update the docstring of `python-indent-def-block-scale'. So, I am also CC'ing this mail to the members of Bug#28475, where `python-indent-def-block-scale' was introduced. I made a separate patch to update the docstring of `python-indent-def-block-scale'. I think the name `python-indent-def-block-scale' itself is a bit misleading, but I have left it as is for compatibility. The following is my proposal of the docstring. What do you think? "Multiplier applied to indentation inside multi-line blocks. The indentation in parens in the block header will be the current indentation plus `python-indent-offset' multiplied by this variable. For example, the arguments are indented as follows if this variable is 1: def do_something( arg1, arg2 ): print('hello') if this variable is 2 (default): def do_something( arg1, arg2): print('hello') This variable has an effect on all blocks, not just def block. This variable only works if the opening paren is not followed by non-whitespace characters on the same line. Modify `python-indent-block-paren-deeper' to customize the case where non-whitespace characters follow the opening paren on the same line." [-- Attachment #2: 0001-Add-a-new-user-option-in-Python-mode-to-improve-the-.patch --] [-- Type: application/octet-stream, Size: 11493 bytes --] From ee243dc685cb0cddeb66c53018633682791dbd0a Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Sun, 16 Apr 2023 22:18:39 +0900 Subject: [PATCH 1/2] Add a new user option in Python mode to improve the indentation * lisp/progmodes/python.el (python-indent-block-paren-deeper): New user option. (python-indent-context): Add a new context :inside-paren-from-block. (python-indent--calculate-indentation): Modify according to `python-indent-block-paren-deeper' and :inside-paren-from-block. * test/lisp/progmodes/python-tests.el (python-indent-inside-paren-block-1) (python-indent-inside-paren-block-2) (python-indent-inside-paren-block-3) (python-indent-inside-paren-block-4): New tests. (python-indent-inside-paren-5, python-indent-dedenters-8): Modify according to the new context. * etc/NEWS: Document the new user option. (Bug#62696) --- etc/NEWS | 17 ++++ lisp/progmodes/python.el | 57 ++++++++++++-- test/lisp/progmodes/python-tests.el | 116 +++++++++++++++++++++++++++- 3 files changed, 181 insertions(+), 9 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b121002b246..9e318812714 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -276,6 +276,23 @@ distracting and easily confused with actual code, or a significant early aid that relieves you from moving the buffer or reaching for the mouse to consult an error message. +** Python mode + +*** New user option 'python-indent-block-paren-deeper'. +If non-nil, increase the indentation of the lines inside parens in a +header of a block when they are indented to the same level as the body +of the block: + + if (some_expression + and another_expression): + do_something() + +instead of: + + if (some_expression + and another_expression): + do_something() + \f * New Modes and Packages in Emacs 30.1 diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bbabce80b4d..9ae95ecfc1c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1270,6 +1270,31 @@ python-indent-def-block-scale :type 'integer :safe 'natnump) +(defcustom python-indent-block-paren-deeper nil + "Increase indentation inside parens of a block. +If non-nil, increase the indentation of the lines inside parens +in a header of a block when they are indented to the same level +as the body of the block: + + if (some_expression + and another_expression): + do_something() + +instead of: + + if (some_expression + and another_expression): + do_something() + +This variable only works if the opening paren is followed by +non-whitespace characters on the same line. Modify +`python-indent-def-block-scale' to customize the case where +non-whitespace character does not follow the opening paren on the +same line." + :version "30.1" + :type 'boolean + :safe 'booleanp) + (defvar python-indent-current-level 0 "Deprecated var available for compatibility.") @@ -1367,6 +1392,10 @@ python-indent-context - Point is inside a paren with items starting in their own line from a block start. - START is the position of the open paren. +:inside-paren-from-block + - Point is inside a paren from a block start followed by some + items on the same line. + - START is the first non space char position *after* the open paren. :after-backslash - Fallback case when point is after backslash. @@ -1450,12 +1479,16 @@ python-indent-context (starts-in-newline (cons :inside-paren-newline-start start)) ;; General case. - (t (cons :inside-paren - (save-excursion - (goto-char (1+ start)) - (skip-syntax-forward "(" 1) - (skip-syntax-forward " ") - (point)))))))) + (t (let ((after-start (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "(" 1) + (skip-syntax-forward " ") + (point)))) + (if (save-excursion + (python-nav-beginning-of-statement) + (python-info-looking-at-beginning-of-block)) + (cons :inside-paren-from-block after-start) + (cons :inside-paren after-start)))))))) ;; After backslash. ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) (python-info-line-ends-backslash-p @@ -1603,7 +1636,17 @@ python-indent--calculate-indentation (`(,(or :inside-paren-newline-start-from-block) . ,start) (goto-char start) (+ (current-indentation) - (* python-indent-offset python-indent-def-block-scale)))))) + (* python-indent-offset python-indent-def-block-scale))) + (`(,:inside-paren-from-block . ,start) + (goto-char start) + (let ((column (current-column))) + (if (and python-indent-block-paren-deeper + (= column (+ (save-excursion + (python-nav-beginning-of-statement) + (current-indentation)) + python-indent-offset))) + (+ column python-indent-offset) + column)))))) (defun python-indent--calculate-levels (indentation) "Calculate levels list given INDENTATION. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 50153e66da5..60b11d572cf 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -1139,7 +1139,7 @@ python-indent-inside-paren-5 (should (eq (car (python-indent-context)) :no-indent)) (should (= (python-indent-calculate-indentation) 0)) (forward-line 1) - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 7)) (forward-line 1) (should (eq (car (python-indent-context)) :after-block-start)) @@ -1174,6 +1174,118 @@ python-indent-inside-paren-7 ;; This signals an error if the test fails (should (eq (car (python-indent-context)) :inside-paren-newline-start)))) +(ert-deftest python-indent-inside-paren-block-1 () + "`python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-2 () + "`python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + +(ert-deftest python-indent-inside-paren-block-3 () + "With backslash. `python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-4 () + "With backslash. `python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + (ert-deftest python-indent-after-block-1 () "The most simple after-block case that shouldn't fail." (python-tests-with-temp-buffer @@ -1670,7 +1782,7 @@ python-indent-dedenters-8 (should (= (python-indent-calculate-indentation) 0)) (should (= (python-indent-calculate-indentation t) 0)) (python-tests-look-at "a == 4):\n") - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 6)) (python-indent-line) (should (= (python-indent-calculate-indentation t) 4)) -- 2.34.1 [-- Attachment #3: 0002-Improve-docstring-of-python-indent-def-block-scale.patch --] [-- Type: application/octet-stream, Size: 1660 bytes --] From 3b3a0dd9394b7905ad47401e4ce2166d5cb79c10 Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Tue, 18 Apr 2023 22:52:18 +0900 Subject: [PATCH 2/2] Improve docstring of python-indent-def-block-scale * lisp/progmodes/python.el (python-indent-def-block-scale): Improve docstring. (Bug#62696) --- lisp/progmodes/python.el | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 9ae95ecfc1c..3bec400006e 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1265,7 +1265,31 @@ python-indent-trigger-commands :type '(repeat symbol)) (defcustom python-indent-def-block-scale 2 - "Multiplier applied to indentation inside multi-line def blocks." + "Multiplier applied to indentation inside multi-line blocks. +The indentation in parens in the block header will be the current +indentation plus `python-indent-offset' multiplied by this +variable. For example, the arguments are indented as follows if +this variable is 1: + + def do_something( + arg1, + arg2 + ): + print('hello') + +if this variable is 2 (default): + + def do_something( + arg1, + arg2): + print('hello') + +This variable has an effect on all blocks, not just def block. +This variable only works if the opening paren is not followed by +non-whitespace characters on the same line. Modify +`python-indent-block-paren-deeper' to customize the case where +non-whitespace characters follow the opening paren on the same +line." :version "26.1" :type 'integer :safe 'natnump) -- 2.34.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-18 14:23 ` kobarity @ 2023-04-20 8:22 ` Eli Zaretskii 2023-04-20 13:40 ` Gustaf Waldemarson 0 siblings, 1 reply; 14+ messages in thread From: Eli Zaretskii @ 2023-04-20 8:22 UTC (permalink / raw) To: kobarity; +Cc: 62696, npostavs, gustaf.waldemarson, gastove, dgutov > Cc: 62696@debbugs.gnu.org, Dmitry Gutov <dgutov@yandex.ru>, > Ross Donaldson <gastove@gmail.com>, > Noam Postavsky <npostavs@users.sourceforge.net> > Date: Tue, 18 Apr 2023 23:23:35 +0900 > From: kobarity <kobarity@gmail.com> > > Gustaf Waldemarson wrote: > > I think that's a really good idea actually. It might also be a good idea to add a > > negative example (i.e., the black-indentation style you mentioned earlier), or > > a reference to one (maybe to the tests?) > > I think the best way is to update the docstring of > `python-indent-def-block-scale'. So, I am also CC'ing this mail to > the members of Bug#28475, where `python-indent-def-block-scale' was > introduced. > > I made a separate patch to update the docstring of > `python-indent-def-block-scale'. I think the name > `python-indent-def-block-scale' itself is a bit misleading, but I have > left it as is for compatibility. The following is my proposal of the > docstring. What do you think? > > "Multiplier applied to indentation inside multi-line blocks. > The indentation in parens in the block header will be the current > indentation plus `python-indent-offset' multiplied by this > variable. For example, the arguments are indented as follows if > this variable is 1: > > def do_something( > arg1, > arg2 > ): > print('hello') > > if this variable is 2 (default): > > def do_something( > arg1, > arg2): > print('hello') > > This variable has an effect on all blocks, not just def block. > This variable only works if the opening paren is not followed by > non-whitespace characters on the same line. Modify > `python-indent-block-paren-deeper' to customize the case where > non-whitespace characters follow the opening paren on the same > line." Do these two patches replace every other patch posted in this discussion? Are these two patches ready to be installed, or are you still discussing the issue? Thanks. ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-20 8:22 ` Eli Zaretskii @ 2023-04-20 13:40 ` Gustaf Waldemarson 2023-04-20 14:19 ` kobarity 0 siblings, 1 reply; 14+ messages in thread From: Gustaf Waldemarson @ 2023-04-20 13:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 62696, kobarity, npostavs, gastove, dgutov [-- Attachment #1: Type: text/plain, Size: 3084 bytes --] Apologies, I think Kobarity was waiting for a response from me and thus held these up: > I made a separate patch to update the docstring of > `python-indent-def-block-scale'. I think the name > `python-indent-def-block-scale' itself is a bit misleading, but I have > left it as is for compatibility. The following is my proposal of the > docstring. What do you think? It mostly looks good to me, but perhaps it would make sense to still output the closing paren on the same line as the first example? I suppose it might not make sense from a style-perspective, but I guess someone reading through this mostly care about comparing indentation depths > Do these two patches replace every other patch posted in this > discussion? > Are these two patches ready to be installed, or are you still > discussing the issue? I believe that's the case, but I would wait for a response from Kobarity following this. Best regards, Gustaf Den tors 20 apr. 2023 kl 10:22 skrev Eli Zaretskii <eliz@gnu.org>: > > Cc: 62696@debbugs.gnu.org, Dmitry Gutov <dgutov@yandex.ru>, > > Ross Donaldson <gastove@gmail.com>, > > Noam Postavsky <npostavs@users.sourceforge.net> > > Date: Tue, 18 Apr 2023 23:23:35 +0900 > > From: kobarity <kobarity@gmail.com> > > > > Gustaf Waldemarson wrote: > > > I think that's a really good idea actually. It might also be a good > idea to add a > > > negative example (i.e., the black-indentation style you mentioned > earlier), or > > > a reference to one (maybe to the tests?) > > > > I think the best way is to update the docstring of > > `python-indent-def-block-scale'. So, I am also CC'ing this mail to > > the members of Bug#28475, where `python-indent-def-block-scale' was > > introduced. > > > > I made a separate patch to update the docstring of > > `python-indent-def-block-scale'. I think the name > > `python-indent-def-block-scale' itself is a bit misleading, but I have > > left it as is for compatibility. The following is my proposal of the > > docstring. What do you think? > > > > "Multiplier applied to indentation inside multi-line blocks. > > The indentation in parens in the block header will be the current > > indentation plus `python-indent-offset' multiplied by this > > variable. For example, the arguments are indented as follows if > > this variable is 1: > > > > def do_something( > > arg1, > > arg2 > > ): > > print('hello') > > > > if this variable is 2 (default): > > > > def do_something( > > arg1, > > arg2): > > print('hello') > > > > This variable has an effect on all blocks, not just def block. > > This variable only works if the opening paren is not followed by > > non-whitespace characters on the same line. Modify > > `python-indent-block-paren-deeper' to customize the case where > > non-whitespace characters follow the opening paren on the same > > line." > > Do these two patches replace every other patch posted in this > discussion? > > Are these two patches ready to be installed, or are you still > discussing the issue? > > Thanks. > [-- Attachment #2: Type: text/html, Size: 4431 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-20 13:40 ` Gustaf Waldemarson @ 2023-04-20 14:19 ` kobarity 2023-04-20 17:44 ` Gustaf Waldemarson 2023-04-22 9:33 ` Eli Zaretskii 0 siblings, 2 replies; 14+ messages in thread From: kobarity @ 2023-04-20 14:19 UTC (permalink / raw) To: Gustaf Waldemarson; +Cc: 62696, Eli Zaretskii, npostavs, gastove, dgutov [-- Attachment #1: Type: text/plain, Size: 1086 bytes --] Gustaf Waldemarson wrote: > It mostly looks good to me, but perhaps it would make sense to still output > the closing paren on the same line as the first example? I suppose it might > not make sense from a style-perspective, but I guess someone reading through > this mostly care about comparing indentation depths Do you mean def do_something( arg1, arg2): print('hello') is better than the following? def do_something( arg1, arg2 ): print('hello') If so, I think it is still good. I updated the patches. > > Do these two patches replace every other patch posted in this > > discussion? > > Are these two patches ready to be installed, or are you still > > discussing the issue? > > I believe that's the case, but I would wait for a response from Kobarity > following this. Yes, I'm attaching the patches which replace every other patches in old mails. I was just waiting to see if anyone had any comments or feedback. So, unless there is an objection, the patches are ready to be installed on the master branch. [-- Attachment #2: 0001-Add-a-new-user-option-in-Python-mode-to-improve-the-.patch --] [-- Type: application/octet-stream, Size: 11493 bytes --] From 71471c48aced70e52568feebb2bc40ebf02d6e7e Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Sun, 16 Apr 2023 22:18:39 +0900 Subject: [PATCH 1/2] Add a new user option in Python mode to improve the indentation * lisp/progmodes/python.el (python-indent-block-paren-deeper): New user option. (python-indent-context): Add a new context :inside-paren-from-block. (python-indent--calculate-indentation): Modify according to `python-indent-block-paren-deeper' and :inside-paren-from-block. * test/lisp/progmodes/python-tests.el (python-indent-inside-paren-block-1) (python-indent-inside-paren-block-2) (python-indent-inside-paren-block-3) (python-indent-inside-paren-block-4): New tests. (python-indent-inside-paren-5, python-indent-dedenters-8): Modify according to the new context. * etc/NEWS: Document the new user option. (Bug#62696) --- etc/NEWS | 17 ++++ lisp/progmodes/python.el | 57 ++++++++++++-- test/lisp/progmodes/python-tests.el | 116 +++++++++++++++++++++++++++- 3 files changed, 181 insertions(+), 9 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b121002b246..9e318812714 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -276,6 +276,23 @@ distracting and easily confused with actual code, or a significant early aid that relieves you from moving the buffer or reaching for the mouse to consult an error message. +** Python mode + +*** New user option 'python-indent-block-paren-deeper'. +If non-nil, increase the indentation of the lines inside parens in a +header of a block when they are indented to the same level as the body +of the block: + + if (some_expression + and another_expression): + do_something() + +instead of: + + if (some_expression + and another_expression): + do_something() + \f * New Modes and Packages in Emacs 30.1 diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bbabce80b4d..9ae95ecfc1c 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1270,6 +1270,31 @@ python-indent-def-block-scale :type 'integer :safe 'natnump) +(defcustom python-indent-block-paren-deeper nil + "Increase indentation inside parens of a block. +If non-nil, increase the indentation of the lines inside parens +in a header of a block when they are indented to the same level +as the body of the block: + + if (some_expression + and another_expression): + do_something() + +instead of: + + if (some_expression + and another_expression): + do_something() + +This variable only works if the opening paren is followed by +non-whitespace characters on the same line. Modify +`python-indent-def-block-scale' to customize the case where +non-whitespace character does not follow the opening paren on the +same line." + :version "30.1" + :type 'boolean + :safe 'booleanp) + (defvar python-indent-current-level 0 "Deprecated var available for compatibility.") @@ -1367,6 +1392,10 @@ python-indent-context - Point is inside a paren with items starting in their own line from a block start. - START is the position of the open paren. +:inside-paren-from-block + - Point is inside a paren from a block start followed by some + items on the same line. + - START is the first non space char position *after* the open paren. :after-backslash - Fallback case when point is after backslash. @@ -1450,12 +1479,16 @@ python-indent-context (starts-in-newline (cons :inside-paren-newline-start start)) ;; General case. - (t (cons :inside-paren - (save-excursion - (goto-char (1+ start)) - (skip-syntax-forward "(" 1) - (skip-syntax-forward " ") - (point)))))))) + (t (let ((after-start (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "(" 1) + (skip-syntax-forward " ") + (point)))) + (if (save-excursion + (python-nav-beginning-of-statement) + (python-info-looking-at-beginning-of-block)) + (cons :inside-paren-from-block after-start) + (cons :inside-paren after-start)))))))) ;; After backslash. ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) (python-info-line-ends-backslash-p @@ -1603,7 +1636,17 @@ python-indent--calculate-indentation (`(,(or :inside-paren-newline-start-from-block) . ,start) (goto-char start) (+ (current-indentation) - (* python-indent-offset python-indent-def-block-scale)))))) + (* python-indent-offset python-indent-def-block-scale))) + (`(,:inside-paren-from-block . ,start) + (goto-char start) + (let ((column (current-column))) + (if (and python-indent-block-paren-deeper + (= column (+ (save-excursion + (python-nav-beginning-of-statement) + (current-indentation)) + python-indent-offset))) + (+ column python-indent-offset) + column)))))) (defun python-indent--calculate-levels (indentation) "Calculate levels list given INDENTATION. diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 50153e66da5..60b11d572cf 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -1139,7 +1139,7 @@ python-indent-inside-paren-5 (should (eq (car (python-indent-context)) :no-indent)) (should (= (python-indent-calculate-indentation) 0)) (forward-line 1) - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 7)) (forward-line 1) (should (eq (car (python-indent-context)) :after-block-start)) @@ -1174,6 +1174,118 @@ python-indent-inside-paren-7 ;; This signals an error if the test fails (should (eq (car (python-indent-context)) :inside-paren-newline-start)))) +(ert-deftest python-indent-inside-paren-block-1 () + "`python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-2 () + "`python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if ('VALUE' in my_unnecessarily_long_dictionary and + some_other_long_condition_case): + do_something() +elif (some_case or + another_case): + do_another() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :at-dedenter-block-start)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 6)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + +(ert-deftest python-indent-inside-paren-block-3 () + "With backslash. `python-indent-block-paren-deeper' set to nil (default). +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 4)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-inside-paren-block-4 () + "With backslash. `python-indent-block-paren-deeper' set to t. +See Bug#62696." + (python-tests-with-temp-buffer + " +if 'VALUE' in my_uncessarily_long_dictionary and\\ + (some_other_long_condition_case or + another_case): + do_something() +" + (let ((python-indent-block-paren-deeper t)) + (python-tests-look-at "if") + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (forward-line 1) + (should (eq (car (python-indent-context)) + :after-backslash-block-continuation)) + (should (= (python-indent-calculate-indentation) 3)) + (forward-line 1) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) + (should (= (python-indent-calculate-indentation) 8)) + (forward-line 1) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4))))) + (ert-deftest python-indent-after-block-1 () "The most simple after-block case that shouldn't fail." (python-tests-with-temp-buffer @@ -1670,7 +1782,7 @@ python-indent-dedenters-8 (should (= (python-indent-calculate-indentation) 0)) (should (= (python-indent-calculate-indentation t) 0)) (python-tests-look-at "a == 4):\n") - (should (eq (car (python-indent-context)) :inside-paren)) + (should (eq (car (python-indent-context)) :inside-paren-from-block)) (should (= (python-indent-calculate-indentation) 6)) (python-indent-line) (should (= (python-indent-calculate-indentation t) 4)) -- 2.34.1 [-- Attachment #3: 0002-Improve-docstring-of-python-indent-def-block-scale.patch --] [-- Type: application/octet-stream, Size: 1653 bytes --] From 0c235d8a82db8881fad3f5c4bc78ab0d9ccf4fc2 Mon Sep 17 00:00:00 2001 From: kobarity <kobarity@gmail.com> Date: Thu, 20 Apr 2023 22:55:29 +0900 Subject: [PATCH 2/2] Improve docstring of python-indent-def-block-scale * lisp/progmodes/python.el (python-indent-def-block-scale): Improve docstring. (Bug#62696) --- lisp/progmodes/python.el | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 9ae95ecfc1c..5bb15c60956 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -1265,7 +1265,30 @@ python-indent-trigger-commands :type '(repeat symbol)) (defcustom python-indent-def-block-scale 2 - "Multiplier applied to indentation inside multi-line def blocks." + "Multiplier applied to indentation inside multi-line blocks. +The indentation in parens in the block header will be the current +indentation plus `python-indent-offset' multiplied by this +variable. For example, the arguments are indented as follows if +this variable is 1: + + def do_something( + arg1, + arg2): + print('hello') + +if this variable is 2 (default): + + def do_something( + arg1, + arg2): + print('hello') + +This variable has an effect on all blocks, not just def block. +This variable only works if the opening paren is not followed by +non-whitespace characters on the same line. Modify +`python-indent-block-paren-deeper' to customize the case where +non-whitespace characters follow the opening paren on the same +line." :version "26.1" :type 'integer :safe 'natnump) -- 2.34.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-20 14:19 ` kobarity @ 2023-04-20 17:44 ` Gustaf Waldemarson 2023-04-22 9:33 ` Eli Zaretskii 1 sibling, 0 replies; 14+ messages in thread From: Gustaf Waldemarson @ 2023-04-20 17:44 UTC (permalink / raw) To: kobarity; +Cc: 62696, Eli Zaretskii, npostavs, gastove, dgutov [-- Attachment #1: Type: text/plain, Size: 1400 bytes --] > If so, I think it is still good. I updated the patches. Yes, as long as the examples are both consistent with the parenthesis they are good to me! Best regards, Gustaf Den tors 20 apr. 2023 kl 16:19 skrev kobarity <kobarity@gmail.com>: > > Gustaf Waldemarson wrote: > > It mostly looks good to me, but perhaps it would make sense to still > output > > the closing paren on the same line as the first example? I suppose it > might > > not make sense from a style-perspective, but I guess someone reading > through > > this mostly care about comparing indentation depths > > Do you mean > > def do_something( > arg1, > arg2): > print('hello') > > is better than the following? > > def do_something( > arg1, > arg2 > ): > print('hello') > > If so, I think it is still good. I updated the patches. > > > > Do these two patches replace every other patch posted in this > > > discussion? > > > Are these two patches ready to be installed, or are you still > > > discussing the issue? > > > > I believe that's the case, but I would wait for a response from Kobarity > > following this. > > Yes, I'm attaching the patches which replace every other patches in > old mails. I was just waiting to see if anyone had any comments or > feedback. So, unless there is an objection, the patches are ready to > be installed on the master branch. > [-- Attachment #2: Type: text/html, Size: 2124 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#62696: python.el: Extra indentation for conditionals 2023-04-20 14:19 ` kobarity 2023-04-20 17:44 ` Gustaf Waldemarson @ 2023-04-22 9:33 ` Eli Zaretskii 1 sibling, 0 replies; 14+ messages in thread From: Eli Zaretskii @ 2023-04-22 9:33 UTC (permalink / raw) To: kobarity; +Cc: 62696-done, npostavs, gustaf.waldemarson, gastove, dgutov > Date: Thu, 20 Apr 2023 23:19:51 +0900 > From: kobarity <kobarity@gmail.com> > Cc: Eli Zaretskii <eliz@gnu.org>, > 62696@debbugs.gnu.org, > dgutov@yandex.ru, > gastove@gmail.com, > npostavs@users.sourceforge.net > > > > Do these two patches replace every other patch posted in this > > > discussion? > > > Are these two patches ready to be installed, or are you still > > > discussing the issue? > > > > I believe that's the case, but I would wait for a response from Kobarity > > following this. > > Yes, I'm attaching the patches which replace every other patches in > old mails. I was just waiting to see if anyone had any comments or > feedback. So, unless there is an objection, the patches are ready to > be installed on the master branch. Thanks, installed on the master branch, and closing the bug. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2023-04-22 9:33 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-04-06 12:47 bug#62696: python.el: Extra indentation for conditionals Gustaf Waldemarson 2023-04-09 12:11 ` kobarity 2023-04-10 11:11 ` Gustaf Waldemarson 2023-04-10 15:21 ` kobarity 2023-04-11 11:11 ` Gustaf Waldemarson 2023-04-12 15:26 ` kobarity 2023-04-16 13:24 ` kobarity 2023-04-16 15:49 ` Gustaf Waldemarson 2023-04-18 14:23 ` kobarity 2023-04-20 8:22 ` Eli Zaretskii 2023-04-20 13:40 ` Gustaf Waldemarson 2023-04-20 14:19 ` kobarity 2023-04-20 17:44 ` Gustaf Waldemarson 2023-04-22 9:33 ` Eli Zaretskii
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).