0

I want to make a few customizations to cmake-model.el. The big-picture view of this lisp file is as follows:

...

;; This function I want to modify
(defun cmake-indent ()
  ...
  )

...

;; Mode definition.
;;
;;;###autoload
(define-derived-mode cmake-mode cmake--parent-mode "CMake"
  "Major mode for editing CMake source files."
  ...
  )

What I want to do is to create a minor mode ros-mode which would override the cmake-indent() function with my own, but keep everything else the same compared to the original cmake-mode.el. The mode line should show ROS when the minor mode is active.

I have no experience with creating minor modes, but I feel like this should be easy for someone with experience. Thank you for helping!

  • The key ingredient is this line: (set (make-local-variable 'indent-line-function) 'cmake-indent) All you need to do is change it to something like (set (make-local-variable 'indent-line-function) 'my-cmake-indent) where your new function is called my-cmake-indent. You don't really need a minor-mode, but you can Google that if you want -- you only need that one (1) line of code and change the mode-line lighter to " ROS" and you are done. You can also Google things like: setq "indent-line-function" emacs to see other examples. – lawlist Nov 8 '16 at 11:18
  • That sounds like what I need. Would you mind writing it more fully as an answer, preferably adding a check to make sure that cmake-mode is available? – space_voyager Nov 8 '16 at 11:24
  • I have a major project today and was just waiting for the coffee to brew while reading the latest threads. I'll need to let another forum participant take over from here . . . :) Your example uses a major-mode (which is not what you want) -- you may wish to instead Google for: "define-minor-mode" emacs And, of course, you want to restore the original value of indent-line-function when the minor-mode is turned off. – lawlist Nov 8 '16 at 11:25
  • 1
    Wouldn't it be better to automatically detect that you are working with ROS-specific files and invoke a major ros-mode in the first place (with all the desired personal configurations) instead of cmake-mode? Or even if you have to invoke it manually, wouldn't a major mode still fit the bill? (i.e. would you ever want to toggle a minor ros-mode on and off again for any given file? It sounds like you would just want it on for such files?) – phils Nov 8 '16 at 12:59
  • 1
    I recommend working with @phils, as that participant is highly knowledegable. (define-minor-mode ros-mode "A minor-mode for working with ROS (Robot Operating System)-specific files." :init-value nil :lighter " ROS" :keymap nil :global nil :group 'cmake (cond (ros-mode (setq-local indent-line-function 'my-cmake-indent) (when (called-interactively-p 'any) (message "Turned ON 'ros-mode'."))) (t (if (eq major-mode 'cmake-mode) (setq-local indent-line-function 'cmake-indent) (kill-local-variable 'indent-line-function)) (when (called-interactively-p 'any) (message "Turned OFF 'ros-mode'."))))) – lawlist Nov 8 '16 at 13:33
1

I ended up going for a derived major mode as suggested by phils. I wrote in ~/.emacs.d/lisp/ros-cmake-mode.el:

(require 'cmake-mode)

(defun ros-cmake-indent ()
   ;; my code here...
  )

;;;###autoload
(define-derived-mode ros-cmake-mode cmake-mode "CMake[ROS]"
  "Major mode for editing ROS CMakeLists.txt files."

  ;; Setup indentation function.
  (set (make-local-variable 'indent-line-function) 'ros-cmake-indent))

(provide 'ros-cmake-mode)

Then in ~/.emacs.d/lisp/init.el (using use-package):

(use-package cmake-mode
  ;; major-mode for editing CMake sources
  :load-path "lisp/"
  :config
  (add-to-list 'auto-mode-alist '("\\.cmake\\'" . cmake-mode))
  (autoload 'cmake-mode "lisp/cmake-mode.el" t))

(use-package ros-cmake-mode
  ;; major-mode for editing CMakeLists.txt files with ROS-style indentation
  :load-path "lisp/"
  :config
  (add-to-list 'auto-mode-alist '("CMakeLists\\.txt\\'" . ros-cmake-mode))
  (autoload 'ros-cmake-mode "lisp/ros-cmake-mode.el" t))

When I open a CMakeLists.txt file, the major mode CMake[ROS] is used by default. In case I want to switch to CMake major mode (as provided by cmake-mode.el), I can type M-x cmake-mode RET.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.